Browse code

lavfi: add drawutils

Add drawutils.h and drawutils.c, and use them in the pad filter.
The new functions are going to be shared by other filters.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Stefano Sabatini authored on 2011/02/21 07:42:17
Showing 4 changed files
... ...
@@ -12,6 +12,7 @@ OBJS = allfilters.o                                                     \
12 12
        avfilter.o                                                       \
13 13
        avfiltergraph.o                                                  \
14 14
        defaults.o                                                       \
15
+       drawutils.o                                                      \
15 16
        formats.o                                                        \
16 17
        graphparser.o                                                    \
17 18
 
18 19
new file mode 100644
... ...
@@ -0,0 +1,117 @@
0
+/*
1
+ * This file is part of FFmpeg.
2
+ *
3
+ * FFmpeg is free software; you can redistribute it and/or
4
+ * modify it under the terms of the GNU Lesser General Public
5
+ * License as published by the Free Software Foundation; either
6
+ * version 2.1 of the License, or (at your option) any later version.
7
+ *
8
+ * FFmpeg is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
+ * Lesser General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU Lesser General Public
14
+ * License along with FFmpeg; if not, write to the Free Software
15
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
+ */
17
+
18
+#include "libavutil/avutil.h"
19
+#include "libavutil/colorspace.h"
20
+#include "libavutil/pixdesc.h"
21
+#include "drawutils.h"
22
+
23
+enum { RED = 0, GREEN, BLUE, ALPHA };
24
+
25
+int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w, uint8_t dst_color[4],
26
+                            enum PixelFormat pix_fmt, uint8_t rgba_color[4],
27
+                            int *is_packed_rgba, uint8_t rgba_map_ptr[4])
28
+{
29
+    uint8_t rgba_map[4] = {0};
30
+    int i;
31
+    const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
32
+    int hsub = pix_desc->log2_chroma_w;
33
+
34
+    *is_packed_rgba = 1;
35
+    switch (pix_fmt) {
36
+    case PIX_FMT_ARGB:  rgba_map[ALPHA] = 0; rgba_map[RED  ] = 1; rgba_map[GREEN] = 2; rgba_map[BLUE ] = 3; break;
37
+    case PIX_FMT_ABGR:  rgba_map[ALPHA] = 0; rgba_map[BLUE ] = 1; rgba_map[GREEN] = 2; rgba_map[RED  ] = 3; break;
38
+    case PIX_FMT_RGBA:
39
+    case PIX_FMT_RGB24: rgba_map[RED  ] = 0; rgba_map[GREEN] = 1; rgba_map[BLUE ] = 2; rgba_map[ALPHA] = 3; break;
40
+    case PIX_FMT_BGRA:
41
+    case PIX_FMT_BGR24: rgba_map[BLUE ] = 0; rgba_map[GREEN] = 1; rgba_map[RED  ] = 2; rgba_map[ALPHA] = 3; break;
42
+    default:
43
+        *is_packed_rgba = 0;
44
+    }
45
+
46
+    if (*is_packed_rgba) {
47
+        pixel_step[0] = (av_get_bits_per_pixel(pix_desc))>>3;
48
+        for (i = 0; i < 4; i++)
49
+            dst_color[rgba_map[i]] = rgba_color[i];
50
+
51
+        line[0] = av_malloc(w * pixel_step[0]);
52
+        for (i = 0; i < w; i++)
53
+            memcpy(line[0] + i * pixel_step[0], dst_color, pixel_step[0]);
54
+        if (rgba_map_ptr)
55
+            memcpy(rgba_map_ptr, rgba_map, sizeof(rgba_map[0]) * 4);
56
+    } else {
57
+        int plane;
58
+
59
+        dst_color[0] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);
60
+        dst_color[1] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
61
+        dst_color[2] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
62
+        dst_color[3] = rgba_color[3];
63
+
64
+        for (plane = 0; plane < 4; plane++) {
65
+            int line_size;
66
+            int hsub1 = (plane == 1 || plane == 2) ? hsub : 0;
67
+
68
+            pixel_step[plane] = 1;
69
+            line_size = (w >> hsub1) * pixel_step[plane];
70
+            line[plane] = av_malloc(line_size);
71
+            memset(line[plane], dst_color[plane], line_size);
72
+        }
73
+    }
74
+
75
+    return 0;
76
+}
77
+
78
+void ff_draw_rectangle(uint8_t *dst[4], int dst_linesize[4],
79
+                       uint8_t *src[4], int pixelstep[4],
80
+                       int hsub, int vsub, int x, int y, int w, int h)
81
+{
82
+    int i, plane;
83
+    uint8_t *p;
84
+
85
+    for (plane = 0; plane < 4 && dst[plane]; plane++) {
86
+        int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
87
+        int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
88
+
89
+        p = dst[plane] + (y >> vsub1) * dst_linesize[plane];
90
+        for (i = 0; i < (h >> vsub1); i++) {
91
+            memcpy(p + (x >> hsub1) * pixelstep[plane],
92
+                   src[plane], (w >> hsub1) * pixelstep[plane]);
93
+            p += dst_linesize[plane];
94
+        }
95
+    }
96
+}
97
+
98
+void ff_copy_rectangle(uint8_t *dst[4], int dst_linesize[4],
99
+                       uint8_t *src[4], int src_linesize[4], int pixelstep[4],
100
+                       int hsub, int vsub, int x, int y, int y2, int w, int h)
101
+{
102
+    int i, plane;
103
+    uint8_t *p;
104
+
105
+    for (plane = 0; plane < 4 && dst[plane]; plane++) {
106
+        int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
107
+        int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
108
+
109
+        p = dst[plane] + (y >> vsub1) * dst_linesize[plane];
110
+        for (i = 0; i < (h >> vsub1); i++) {
111
+            memcpy(p + (x >> hsub1) * pixelstep[plane],
112
+                   src[plane] + src_linesize[plane]*(i+(y2>>vsub1)), (w >> hsub1) * pixelstep[plane]);
113
+            p += dst_linesize[plane];
114
+        }
115
+    }
116
+}
0 117
new file mode 100644
... ...
@@ -0,0 +1,43 @@
0
+/*
1
+ * This file is part of FFmpeg.
2
+ *
3
+ * FFmpeg is free software; you can redistribute it and/or
4
+ * modify it under the terms of the GNU Lesser General Public
5
+ * License as published by the Free Software Foundation; either
6
+ * version 2.1 of the License, or (at your option) any later version.
7
+ *
8
+ * FFmpeg is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
+ * Lesser General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU Lesser General Public
14
+ * License along with FFmpeg; if not, write to the Free Software
15
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
+ */
17
+
18
+#ifndef AVFILTER_DRAWUTILS_H
19
+#define AVFILTER_DRAWUTILS_H
20
+
21
+/**
22
+ * @file
23
+ * misc drawing utilities
24
+ */
25
+
26
+#include <stdint.h>
27
+#include "libavutil/pixfmt.h"
28
+
29
+int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w,
30
+                            uint8_t dst_color[4],
31
+                            enum PixelFormat pix_fmt, uint8_t rgba_color[4],
32
+                            int *is_packed_rgba, uint8_t rgba_map[4]);
33
+
34
+void ff_draw_rectangle(uint8_t *dst[4], int dst_linesize[4],
35
+                       uint8_t *src[4], int pixelstep[4],
36
+                       int hsub, int vsub, int x, int y, int w, int h);
37
+
38
+void ff_copy_rectangle(uint8_t *dst[4], int dst_linesize[4],
39
+                       uint8_t *src[4], int src_linesize[4], int pixelstep[4],
40
+                       int hsub, int vsub, int x, int y, int y2, int w, int h);
41
+
42
+#endif /* AVFILTER_DRAWUTILS_H */
... ...
@@ -30,94 +30,7 @@
30 30
 #include "libavutil/avassert.h"
31 31
 #include "libavutil/imgutils.h"
32 32
 #include "libavutil/parseutils.h"
33
-
34
-enum { RED = 0, GREEN, BLUE, ALPHA };
35
-
36
-static int fill_line_with_color(uint8_t *line[4], int line_step[4], int w, uint8_t color[4],
37
-                                enum PixelFormat pix_fmt, uint8_t rgba_color[4], int *is_packed_rgba)
38
-{
39
-    uint8_t rgba_map[4] = {0};
40
-    int i;
41
-    const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
42
-    int hsub = pix_desc->log2_chroma_w;
43
-
44
-    *is_packed_rgba = 1;
45
-    switch (pix_fmt) {
46
-    case PIX_FMT_ARGB:  rgba_map[ALPHA] = 0; rgba_map[RED  ] = 1; rgba_map[GREEN] = 2; rgba_map[BLUE ] = 3; break;
47
-    case PIX_FMT_ABGR:  rgba_map[ALPHA] = 0; rgba_map[BLUE ] = 1; rgba_map[GREEN] = 2; rgba_map[RED  ] = 3; break;
48
-    case PIX_FMT_RGBA:
49
-    case PIX_FMT_RGB24: rgba_map[RED  ] = 0; rgba_map[GREEN] = 1; rgba_map[BLUE ] = 2; rgba_map[ALPHA] = 3; break;
50
-    case PIX_FMT_BGRA:
51
-    case PIX_FMT_BGR24: rgba_map[BLUE ] = 0; rgba_map[GREEN] = 1; rgba_map[RED  ] = 2; rgba_map[ALPHA] = 3; break;
52
-    default:
53
-        *is_packed_rgba = 0;
54
-    }
55
-
56
-    if (*is_packed_rgba) {
57
-        line_step[0] = (av_get_bits_per_pixel(pix_desc))>>3;
58
-        for (i = 0; i < 4; i++)
59
-            color[rgba_map[i]] = rgba_color[i];
60
-
61
-        line[0] = av_malloc(w * line_step[0]);
62
-        for (i = 0; i < w; i++)
63
-            memcpy(line[0] + i * line_step[0], color, line_step[0]);
64
-    } else {
65
-        int plane;
66
-
67
-        color[RED  ] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);
68
-        color[GREEN] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
69
-        color[BLUE ] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
70
-        color[ALPHA] = rgba_color[3];
71
-
72
-        for (plane = 0; plane < 4; plane++) {
73
-            int line_size;
74
-            int hsub1 = (plane == 1 || plane == 2) ? hsub : 0;
75
-
76
-            line_step[plane] = 1;
77
-            line_size = (w >> hsub1) * line_step[plane];
78
-            line[plane] = av_malloc(line_size);
79
-            memset(line[plane], color[plane], line_size);
80
-        }
81
-    }
82
-
83
-    return 0;
84
-}
85
-
86
-static void draw_rectangle(AVFilterBufferRef *outpic, uint8_t *line[4], int line_step[4],
87
-                           int hsub, int vsub, int x, int y, int w, int h)
88
-{
89
-    int i, plane;
90
-    uint8_t *p;
91
-
92
-    for (plane = 0; plane < 4 && outpic->data[plane]; plane++) {
93
-        int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
94
-        int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
95
-
96
-        p = outpic->data[plane] + (y >> vsub1) * outpic->linesize[plane];
97
-        for (i = 0; i < (h >> vsub1); i++) {
98
-            memcpy(p + (x >> hsub1) * line_step[plane], line[plane], (w >> hsub1) * line_step[plane]);
99
-            p += outpic->linesize[plane];
100
-        }
101
-    }
102
-}
103
-
104
-static void copy_rectangle(AVFilterBufferRef *outpic,uint8_t *line[4], int line_step[4], int linesize[4],
105
-                           int hsub, int vsub, int x, int y, int y2, int w, int h)
106
-{
107
-    int i, plane;
108
-    uint8_t *p;
109
-
110
-    for (plane = 0; plane < 4 && outpic->data[plane]; plane++) {
111
-        int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
112
-        int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
113
-
114
-        p = outpic->data[plane] + (y >> vsub1) * outpic->linesize[plane];
115
-        for (i = 0; i < (h >> vsub1); i++) {
116
-            memcpy(p + (x >> hsub1) * line_step[plane], line[plane] + linesize[plane]*(i+(y2>>vsub1)), (w >> hsub1) * line_step[plane]);
117
-            p += outpic->linesize[plane];
118
-        }
119
-    }
120
-}
33
+#include "drawutils.h"
121 34
 
122 35
 static int query_formats(AVFilterContext *ctx)
123 36
 {
... ...
@@ -210,8 +123,8 @@ static int config_input(AVFilterLink *inlink)
210 210
     pad->in_h = inlink->h & ~((1 << pad->vsub) - 1);
211 211
 
212 212
     memcpy(rgba_color, pad->color, sizeof(rgba_color));
213
-    fill_line_with_color(pad->line, pad->line_step, pad->w, pad->color,
214
-                         inlink->format, rgba_color, &is_packed_rgba);
213
+    ff_fill_line_with_color(pad->line, pad->line_step, pad->w, pad->color,
214
+                            inlink->format, rgba_color, &is_packed_rgba, NULL);
215 215
 
216 216
     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",
217 217
            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,
351 351
     }
352 352
 
353 353
     if (bar_h) {
354
-        draw_rectangle(link->dst->outputs[0]->out_buf,
355
-                       pad->line, pad->line_step, pad->hsub, pad->vsub,
356
-                       0, bar_y, pad->w, bar_h);
354
+        ff_draw_rectangle(link->dst->outputs[0]->out_buf->data,
355
+                          link->dst->outputs[0]->out_buf->linesize,
356
+                          pad->line, pad->line_step, pad->hsub, pad->vsub,
357
+                          0, bar_y, pad->w, bar_h);
357 358
         avfilter_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir);
358 359
     }
359 360
 }
... ...
@@ -374,18 +288,20 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
374 374
     draw_send_bar_slice(link, y, h, slice_dir, 1);
375 375
 
376 376
     /* left border */
377
-    draw_rectangle(outpic, pad->line, pad->line_step, pad->hsub, pad->vsub,
378
-                   0, y, pad->x, h);
377
+    ff_draw_rectangle(outpic->data, outpic->linesize, pad->line, pad->line_step,
378
+                      pad->hsub, pad->vsub, 0, y, pad->x, h);
379 379
 
380 380
     if(pad->needs_copy){
381
-        copy_rectangle(outpic,
382
-                       inpic->data, pad->line_step, inpic->linesize, pad->hsub, pad->vsub,
383
-                       pad->x, y, y-pad->y, inpic->video->w, h);
381
+        ff_copy_rectangle(outpic->data, outpic->linesize,
382
+                          inpic->data, inpic->linesize, pad->line_step,
383
+                          pad->hsub, pad->vsub,
384
+                          pad->x, y, y-pad->y, inpic->video->w, h);
384 385
     }
385 386
 
386 387
     /* right border */
387
-    draw_rectangle(outpic, pad->line, pad->line_step, pad->hsub, pad->vsub,
388
-                   pad->x + pad->in_w, y, pad->w - pad->x - pad->in_w, h);
388
+    ff_draw_rectangle(outpic->data, outpic->linesize,
389
+                      pad->line, pad->line_step, pad->hsub, pad->vsub,
390
+                      pad->x + pad->in_w, y, pad->w - pad->x - pad->in_w, h);
389 391
     avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir);
390 392
 
391 393
     draw_send_bar_slice(link, y, h, slice_dir, -1);
... ...
@@ -488,8 +404,8 @@ static int color_config_props(AVFilterLink *inlink)
488 488
         return AVERROR(EINVAL);
489 489
 
490 490
     memcpy(rgba_color, color->color, sizeof(rgba_color));
491
-    fill_line_with_color(color->line, color->line_step, color->w, color->color,
492
-                         inlink->format, rgba_color, &is_packed_rgba);
491
+    ff_fill_line_with_color(color->line, color->line_step, color->w, color->color,
492
+                            inlink->format, rgba_color, &is_packed_rgba, NULL);
493 493
 
494 494
     av_log(ctx, AV_LOG_INFO, "w:%d h:%d r:%d/%d color:0x%02x%02x%02x%02x[%s]\n",
495 495
            color->w, color->h, color->time_base.den, color->time_base.num,
... ...
@@ -510,9 +426,9 @@ static int color_request_frame(AVFilterLink *link)
510 510
     picref->pos                 = 0;
511 511
 
512 512
     avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0));
513
-    draw_rectangle(picref,
514
-                   color->line, color->line_step, color->hsub, color->vsub,
515
-                   0, 0, color->w, color->h);
513
+    ff_draw_rectangle(picref->data, picref->linesize,
514
+                      color->line, color->line_step, color->hsub, color->vsub,
515
+                      0, 0, color->w, color->h);
516 516
     avfilter_draw_slice(link, 0, color->h, 1);
517 517
     avfilter_end_frame(link);
518 518
     avfilter_unref_buffer(picref);