[FFmpeg-devel] [PATCH] lavfi: add drawutils

Stefano Sabatini stefano.sabatini-lala
Sun Feb 20 23:42:17 CET 2011


Add drawutils.h and drawutils.c, and use them in the pad filter.
The new functions are going to be shared by other filters.
---
 libavfilter/Makefile    |    1 +
 libavfilter/drawutils.c |  117 +++++++++++++++++++++++++++++++++++++++++++
 libavfilter/drawutils.h |   43 ++++++++++++++++
 libavfilter/vf_pad.c    |  126 ++++++++---------------------------------------
 4 files changed, 182 insertions(+), 105 deletions(-)
 create mode 100644 libavfilter/drawutils.c
 create mode 100644 libavfilter/drawutils.h

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index abb68c8..30c75bd 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -11,6 +11,7 @@ OBJS = allfilters.o                                                     \
        avfilter.o                                                       \
        avfiltergraph.o                                                  \
        defaults.o                                                       \
+       drawutils.o                                                      \
        formats.o                                                        \
        graphparser.o                                                    \
 
diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c
new file mode 100644
index 0000000..dd9ceff
--- /dev/null
+++ b/libavfilter/drawutils.c
@@ -0,0 +1,117 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/avutil.h"
+#include "libavutil/colorspace.h"
+#include "libavutil/pixdesc.h"
+#include "drawutils.h"
+
+enum { RED = 0, GREEN, BLUE, ALPHA };
+
+int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w, uint8_t dst_color[4],
+                            enum PixelFormat pix_fmt, uint8_t rgba_color[4],
+                            int *is_packed_rgba, uint8_t rgba_map_ptr[4])
+{
+    uint8_t rgba_map[4] = {0};
+    int i;
+    const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
+    int hsub = pix_desc->log2_chroma_w;
+
+    *is_packed_rgba = 1;
+    switch (pix_fmt) {
+    case PIX_FMT_ARGB:  rgba_map[ALPHA] = 0; rgba_map[RED  ] = 1; rgba_map[GREEN] = 2; rgba_map[BLUE ] = 3; break;
+    case PIX_FMT_ABGR:  rgba_map[ALPHA] = 0; rgba_map[BLUE ] = 1; rgba_map[GREEN] = 2; rgba_map[RED  ] = 3; break;
+    case PIX_FMT_RGBA:
+    case PIX_FMT_RGB24: rgba_map[RED  ] = 0; rgba_map[GREEN] = 1; rgba_map[BLUE ] = 2; rgba_map[ALPHA] = 3; break;
+    case PIX_FMT_BGRA:
+    case PIX_FMT_BGR24: rgba_map[BLUE ] = 0; rgba_map[GREEN] = 1; rgba_map[RED  ] = 2; rgba_map[ALPHA] = 3; break;
+    default:
+        *is_packed_rgba = 0;
+    }
+
+    if (*is_packed_rgba) {
+        pixel_step[0] = (av_get_bits_per_pixel(pix_desc))>>3;
+        for (i = 0; i < 4; i++)
+            dst_color[rgba_map[i]] = rgba_color[i];
+
+        line[0] = av_malloc(w * pixel_step[0]);
+        for (i = 0; i < w; i++)
+            memcpy(line[0] + i * pixel_step[0], dst_color, pixel_step[0]);
+        if (rgba_map_ptr)
+            memcpy(rgba_map_ptr, rgba_map, sizeof(rgba_map[0]) * 4);
+    } else {
+        int plane;
+
+        dst_color[0] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);
+        dst_color[1] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
+        dst_color[2] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
+        dst_color[3] = rgba_color[3];
+
+        for (plane = 0; plane < 4; plane++) {
+            int line_size;
+            int hsub1 = (plane == 1 || plane == 2) ? hsub : 0;
+
+            pixel_step[plane] = 1;
+            line_size = (w >> hsub1) * pixel_step[plane];
+            line[plane] = av_malloc(line_size);
+            memset(line[plane], dst_color[plane], line_size);
+        }
+    }
+
+    return 0;
+}
+
+void ff_draw_rectangle(uint8_t *dst[4], int dst_linesize[4],
+                       uint8_t *src[4], int pixelstep[4],
+                       int hsub, int vsub, int x, int y, int w, int h)
+{
+    int i, plane;
+    uint8_t *p;
+
+    for (plane = 0; plane < 4 && dst[plane]; plane++) {
+        int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
+        int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
+
+        p = dst[plane] + (y >> vsub1) * dst_linesize[plane];
+        for (i = 0; i < (h >> vsub1); i++) {
+            memcpy(p + (x >> hsub1) * pixelstep[plane],
+                   src[plane], (w >> hsub1) * pixelstep[plane]);
+            p += dst_linesize[plane];
+        }
+    }
+}
+
+void ff_copy_rectangle(uint8_t *dst[4], int dst_linesize[4],
+                       uint8_t *src[4], int src_linesize[4], int pixelstep[4],
+                       int hsub, int vsub, int x, int y, int y2, int w, int h)
+{
+    int i, plane;
+    uint8_t *p;
+
+    for (plane = 0; plane < 4 && dst[plane]; plane++) {
+        int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
+        int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
+
+        p = dst[plane] + (y >> vsub1) * dst_linesize[plane];
+        for (i = 0; i < (h >> vsub1); i++) {
+            memcpy(p + (x >> hsub1) * pixelstep[plane],
+                   src[plane] + src_linesize[plane]*(i+(y2>>vsub1)), (w >> hsub1) * pixelstep[plane]);
+            p += dst_linesize[plane];
+        }
+    }
+}
diff --git a/libavfilter/drawutils.h b/libavfilter/drawutils.h
new file mode 100644
index 0000000..e838660
--- /dev/null
+++ b/libavfilter/drawutils.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFILTER_DRAWUTILS_H
+#define AVFILTER_DRAWUTILS_H
+
+/**
+ * @file
+ * misc drawing utilities
+ */
+
+#include <stdint.h>
+#include "libavutil/pixfmt.h"
+
+int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w,
+                            uint8_t dst_color[4],
+                            enum PixelFormat pix_fmt, uint8_t rgba_color[4],
+                            int *is_packed_rgba, uint8_t rgba_map[4]);
+
+void ff_draw_rectangle(uint8_t *dst[4], int dst_linesize[4],
+                       uint8_t *src[4], int pixelstep[4],
+                       int hsub, int vsub, int x, int y, int w, int h);
+
+void ff_copy_rectangle(uint8_t *dst[4], int dst_linesize[4],
+                       uint8_t *src[4], int src_linesize[4], int pixelstep[4],
+                       int hsub, int vsub, int x, int y, int y2, int w, int h);
+
+#endif /* AVFILTER_DRAWUTILS_H */
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index 7413071..30ec5ba 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -30,94 +30,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/parseutils.h"
-
-enum { RED = 0, GREEN, BLUE, ALPHA };
-
-static int fill_line_with_color(uint8_t *line[4], int line_step[4], int w, uint8_t color[4],
-                                enum PixelFormat pix_fmt, uint8_t rgba_color[4], int *is_packed_rgba)
-{
-    uint8_t rgba_map[4] = {0};
-    int i;
-    const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
-    int hsub = pix_desc->log2_chroma_w;
-
-    *is_packed_rgba = 1;
-    switch (pix_fmt) {
-    case PIX_FMT_ARGB:  rgba_map[ALPHA] = 0; rgba_map[RED  ] = 1; rgba_map[GREEN] = 2; rgba_map[BLUE ] = 3; break;
-    case PIX_FMT_ABGR:  rgba_map[ALPHA] = 0; rgba_map[BLUE ] = 1; rgba_map[GREEN] = 2; rgba_map[RED  ] = 3; break;
-    case PIX_FMT_RGBA:
-    case PIX_FMT_RGB24: rgba_map[RED  ] = 0; rgba_map[GREEN] = 1; rgba_map[BLUE ] = 2; rgba_map[ALPHA] = 3; break;
-    case PIX_FMT_BGRA:
-    case PIX_FMT_BGR24: rgba_map[BLUE ] = 0; rgba_map[GREEN] = 1; rgba_map[RED  ] = 2; rgba_map[ALPHA] = 3; break;
-    default:
-        *is_packed_rgba = 0;
-    }
-
-    if (*is_packed_rgba) {
-        line_step[0] = (av_get_bits_per_pixel(pix_desc))>>3;
-        for (i = 0; i < 4; i++)
-            color[rgba_map[i]] = rgba_color[i];
-
-        line[0] = av_malloc(w * line_step[0]);
-        for (i = 0; i < w; i++)
-            memcpy(line[0] + i * line_step[0], color, line_step[0]);
-    } else {
-        int plane;
-
-        color[RED  ] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);
-        color[GREEN] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
-        color[BLUE ] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
-        color[ALPHA] = rgba_color[3];
-
-        for (plane = 0; plane < 4; plane++) {
-            int line_size;
-            int hsub1 = (plane == 1 || plane == 2) ? hsub : 0;
-
-            line_step[plane] = 1;
-            line_size = (w >> hsub1) * line_step[plane];
-            line[plane] = av_malloc(line_size);
-            memset(line[plane], color[plane], line_size);
-        }
-    }
-
-    return 0;
-}
-
-static void draw_rectangle(AVFilterBufferRef *outpic, uint8_t *line[4], int line_step[4],
-                           int hsub, int vsub, int x, int y, int w, int h)
-{
-    int i, plane;
-    uint8_t *p;
-
-    for (plane = 0; plane < 4 && outpic->data[plane]; plane++) {
-        int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
-        int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
-
-        p = outpic->data[plane] + (y >> vsub1) * outpic->linesize[plane];
-        for (i = 0; i < (h >> vsub1); i++) {
-            memcpy(p + (x >> hsub1) * line_step[plane], line[plane], (w >> hsub1) * line_step[plane]);
-            p += outpic->linesize[plane];
-        }
-    }
-}
-
-static void copy_rectangle(AVFilterBufferRef *outpic,uint8_t *line[4], int line_step[4], int linesize[4],
-                           int hsub, int vsub, int x, int y, int y2, int w, int h)
-{
-    int i, plane;
-    uint8_t *p;
-
-    for (plane = 0; plane < 4 && outpic->data[plane]; plane++) {
-        int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
-        int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
-
-        p = outpic->data[plane] + (y >> vsub1) * outpic->linesize[plane];
-        for (i = 0; i < (h >> vsub1); i++) {
-            memcpy(p + (x >> hsub1) * line_step[plane], line[plane] + linesize[plane]*(i+(y2>>vsub1)), (w >> hsub1) * line_step[plane]);
-            p += outpic->linesize[plane];
-        }
-    }
-}
+#include "drawutils.h"
 
 static int query_formats(AVFilterContext *ctx)
 {
@@ -210,8 +123,8 @@ static int config_input(AVFilterLink *inlink)
     pad->in_h = inlink->h & ~((1 << pad->vsub) - 1);
 
     memcpy(rgba_color, pad->color, sizeof(rgba_color));
-    fill_line_with_color(pad->line, pad->line_step, pad->w, pad->color,
-                         inlink->format, rgba_color, &is_packed_rgba);
+    ff_fill_line_with_color(pad->line, pad->line_step, pad->w, pad->color,
+                            inlink->format, rgba_color, &is_packed_rgba, NULL);
 
     av_log(ctx, AV_LOG_INFO, "w:%d h:%d -> w:%d h:%d x:%d y:%d color:0x%02X%02X%02X%02X[%s]\n",
            inlink->w, inlink->h, pad->w, pad->h, pad->x, pad->y,
@@ -351,9 +264,10 @@ static void draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir,
     }
 
     if (bar_h) {
-        draw_rectangle(link->dst->outputs[0]->out_buf,
-                       pad->line, pad->line_step, pad->hsub, pad->vsub,
-                       0, bar_y, pad->w, bar_h);
+        ff_draw_rectangle(link->dst->outputs[0]->out_buf->data,
+                          link->dst->outputs[0]->out_buf->linesize,
+                          pad->line, pad->line_step, pad->hsub, pad->vsub,
+                          0, bar_y, pad->w, bar_h);
         avfilter_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir);
     }
 }
@@ -374,18 +288,20 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
     draw_send_bar_slice(link, y, h, slice_dir, 1);
 
     /* left border */
-    draw_rectangle(outpic, pad->line, pad->line_step, pad->hsub, pad->vsub,
-                   0, y, pad->x, h);
+    ff_draw_rectangle(outpic->data, outpic->linesize, pad->line, pad->line_step,
+                      pad->hsub, pad->vsub, 0, y, pad->x, h);
 
     if(pad->needs_copy){
-        copy_rectangle(outpic,
-                       inpic->data, pad->line_step, inpic->linesize, pad->hsub, pad->vsub,
-                       pad->x, y, y-pad->y, inpic->video->w, h);
+        ff_copy_rectangle(outpic->data, outpic->linesize,
+                          inpic->data, inpic->linesize, pad->line_step,
+                          pad->hsub, pad->vsub,
+                          pad->x, y, y-pad->y, inpic->video->w, h);
     }
 
     /* right border */
-    draw_rectangle(outpic, pad->line, pad->line_step, pad->hsub, pad->vsub,
-                   pad->x + pad->in_w, y, pad->w - pad->x - pad->in_w, h);
+    ff_draw_rectangle(outpic->data, outpic->linesize,
+                      pad->line, pad->line_step, pad->hsub, pad->vsub,
+                      pad->x + pad->in_w, y, pad->w - pad->x - pad->in_w, h);
     avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir);
 
     draw_send_bar_slice(link, y, h, slice_dir, -1);
@@ -488,8 +404,8 @@ static int color_config_props(AVFilterLink *inlink)
         return AVERROR(EINVAL);
 
     memcpy(rgba_color, color->color, sizeof(rgba_color));
-    fill_line_with_color(color->line, color->line_step, color->w, color->color,
-                         inlink->format, rgba_color, &is_packed_rgba);
+    ff_fill_line_with_color(color->line, color->line_step, color->w, color->color,
+                            inlink->format, rgba_color, &is_packed_rgba, NULL);
 
     av_log(ctx, AV_LOG_INFO, "w:%d h:%d r:%d/%d color:0x%02x%02x%02x%02x[%s]\n",
            color->w, color->h, color->time_base.den, color->time_base.num,
@@ -510,9 +426,9 @@ static int color_request_frame(AVFilterLink *link)
     picref->pos                 = 0;
 
     avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0));
-    draw_rectangle(picref,
-                   color->line, color->line_step, color->hsub, color->vsub,
-                   0, 0, color->w, color->h);
+    ff_draw_rectangle(picref->data, picref->linesize,
+                      color->line, color->line_step, color->hsub, color->vsub,
+                      0, 0, color->w, color->h);
     avfilter_draw_slice(link, 0, color->h, 1);
     avfilter_end_frame(link);
     avfilter_unref_buffer(picref);
-- 
1.7.2.3




More information about the ffmpeg-devel mailing list