[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