[FFmpeg-devel] [PATCH 3/4] Implement and use shareable ff_transpose function.

Stefano Sabatini stefano.sabatini-lala
Sun Oct 17 13:23:36 CEST 2010


---
 libavfilter/Makefile       |    2 +-
 libavfilter/transpose.c    |  108 ++++++++++++++++++++++++++++++++++++++++++++
 libavfilter/transpose.h    |   37 +++++++++++++++
 libavfilter/vf_transpose.c |   88 +++---------------------------------
 4 files changed, 152 insertions(+), 83 deletions(-)
 create mode 100644 libavfilter/transpose.c
 create mode 100644 libavfilter/transpose.h

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 38d2762..532d1c1 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -38,7 +38,7 @@ OBJS-$(CONFIG_PIXELASPECT_FILTER)            += vf_aspect.o
 OBJS-$(CONFIG_SCALE_FILTER)                  += vf_scale.o
 OBJS-$(CONFIG_SETTB_FILTER)                  += vf_settb.o
 OBJS-$(CONFIG_SLICIFY_FILTER)                += vf_slicify.o
-OBJS-$(CONFIG_TRANSPOSE_FILTER)              += vf_transpose.o
+OBJS-$(CONFIG_TRANSPOSE_FILTER)              += transpose.o vf_transpose.o
 OBJS-$(CONFIG_UNSHARP_FILTER)                += vf_unsharp.o
 OBJS-$(CONFIG_VFLIP_FILTER)                  += vf_vflip.o
 OBJS-$(CONFIG_YADIF_FILTER)                  += vf_yadif.o
diff --git a/libavfilter/transpose.c b/libavfilter/transpose.c
new file mode 100644
index 0000000..56d6729
--- /dev/null
+++ b/libavfilter/transpose.c
@@ -0,0 +1,108 @@
+/*
+ * 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/intreadwrite.h"
+#include "transpose.h"
+
+int ff_transpose_query_formats(AVFilterContext *ctx)
+{
+    enum PixelFormat pix_fmts[] = {
+        PIX_FMT_ARGB,         PIX_FMT_RGBA,
+        PIX_FMT_ABGR,         PIX_FMT_BGRA,
+        PIX_FMT_RGB24,        PIX_FMT_BGR24,
+        PIX_FMT_RGB565BE,     PIX_FMT_RGB565LE,
+        PIX_FMT_RGB555BE,     PIX_FMT_RGB555LE,
+        PIX_FMT_BGR565BE,     PIX_FMT_BGR565LE,
+        PIX_FMT_BGR555BE,     PIX_FMT_BGR555LE,
+        PIX_FMT_GRAY16BE,     PIX_FMT_GRAY16LE,
+        PIX_FMT_YUV420P16LE,  PIX_FMT_YUV420P16BE,
+        PIX_FMT_YUV422P16LE,  PIX_FMT_YUV422P16BE,
+        PIX_FMT_YUV444P16LE,  PIX_FMT_YUV444P16BE,
+        PIX_FMT_NV12,         PIX_FMT_NV21,
+        PIX_FMT_RGB8,         PIX_FMT_BGR8,
+        PIX_FMT_RGB4_BYTE,    PIX_FMT_BGR4_BYTE,
+        PIX_FMT_YUV444P,      PIX_FMT_YUV422P,
+        PIX_FMT_YUV420P,      PIX_FMT_YUVJ420P,
+        PIX_FMT_YUV411P,      PIX_FMT_YUV410P,
+        PIX_FMT_YUVJ444P,     PIX_FMT_YUVJ422P,
+        PIX_FMT_YUV440P,      PIX_FMT_YUVJ440P,
+        PIX_FMT_YUVA420P,     PIX_FMT_GRAY8,
+        PIX_FMT_NONE
+    };
+
+    avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
+    return 0;
+}
+
+void ff_transpose(uint8_t *out_planes[4], int out_linesizes[4],
+                  uint8_t *in_planes [4], int in_linesizes [4],
+                  int outw0, int outh0,
+                  int pixsteps[4], int hsub, int vsub,
+                  int dir)
+{
+    int plane;
+
+    for (plane = 0; plane < 4 && out_planes[plane]; plane++) {
+        int hsub1 = plane == 1 || plane == 2 ? hsub : 0;
+        int vsub1 = plane == 1 || plane == 2 ? vsub : 0;
+        int pixstep = pixsteps[plane];
+        int inh  = outw0>>vsub1;
+        int outw = outw0>>hsub1;
+        int outh = outh0>>vsub1;
+        uint8_t *out, *in;
+        int outlinesize, inlinesize;
+        int x, y;
+
+        out = out_planes[plane]; outlinesize = out_linesizes[plane];
+        in  = in_planes [plane]; inlinesize  = in_linesizes [plane];
+
+        if (dir&1) {
+            in +=  in_linesizes[plane] * (inh-1);
+            inlinesize *= -1;
+        }
+
+        if (dir&2) {
+            out += out_linesizes[plane] * (outh-1);
+            outlinesize *= -1;
+        }
+
+        for (y = 0; y < outh; y++) {
+            switch (pixstep) {
+            case 1:
+                for (x = 0; x < outw; x++)
+                    *(out + x) = *(in + x*inlinesize + y);
+                break;
+            case 2:
+                for (x = 0; x < outw; x++)
+                    *((uint16_t *)(out + 2*x)) = *((uint16_t *)(in + x*inlinesize + y*2));
+                break;
+            case 3:
+                for (x = 0; x < outw; x++) {
+                    int32_t v = AV_RB24(in + x*inlinesize + y*3);
+                    AV_WB24(out + 3*x, v);
+                }
+                break;
+            case 4:
+                for (x = 0; x < outw; x++)
+                    *((uint32_t *)(out + 4*x)) = *((uint32_t *)(in + x*inlinesize + y*4));
+                break;
+            }
+            out += outlinesize;
+        }
+    }
+}
diff --git a/libavfilter/transpose.h b/libavfilter/transpose.h
new file mode 100644
index 0000000..da93168
--- /dev/null
+++ b/libavfilter/transpose.h
@@ -0,0 +1,37 @@
+/*
+ * 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_TRANSPOSE_H
+#define AVFILTER_TRANSPOSE_H
+
+/**
+ * @file
+ * transpose shared functions
+ */
+
+#include "avfilter.h"
+
+int ff_transpose_query_formats(AVFilterContext *ctx);
+
+void ff_transpose(uint8_t *out_planes[4], int out_linesizes[4],
+                  uint8_t *in_planes [4], int in_linesizes [4],
+                  int outw, int inh,
+                  int pixsteps[4], int hsub, int vsub,
+                  int dir);
+
+#endif /* AVFILTER_TRANSPOSE_H */
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index 94737be..09f56d5 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -24,10 +24,10 @@
  * transposition filter
  */
 
-#include "libavutil/intreadwrite.h"
 #include "libavutil/pixdesc.h"
 #include "libavcore/imgutils.h"
 #include "avfilter.h"
+#include "transpose.h"
 
 typedef struct {
     int hsub, vsub;
@@ -56,36 +56,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
     return 0;
 }
 
-static int query_formats(AVFilterContext *ctx)
-{
-    enum PixelFormat pix_fmts[] = {
-        PIX_FMT_ARGB,         PIX_FMT_RGBA,
-        PIX_FMT_ABGR,         PIX_FMT_BGRA,
-        PIX_FMT_RGB24,        PIX_FMT_BGR24,
-        PIX_FMT_RGB565BE,     PIX_FMT_RGB565LE,
-        PIX_FMT_RGB555BE,     PIX_FMT_RGB555LE,
-        PIX_FMT_BGR565BE,     PIX_FMT_BGR565LE,
-        PIX_FMT_BGR555BE,     PIX_FMT_BGR555LE,
-        PIX_FMT_GRAY16BE,     PIX_FMT_GRAY16LE,
-        PIX_FMT_YUV420P16LE,  PIX_FMT_YUV420P16BE,
-        PIX_FMT_YUV422P16LE,  PIX_FMT_YUV422P16BE,
-        PIX_FMT_YUV444P16LE,  PIX_FMT_YUV444P16BE,
-        PIX_FMT_NV12,         PIX_FMT_NV21,
-        PIX_FMT_RGB8,         PIX_FMT_BGR8,
-        PIX_FMT_RGB4_BYTE,    PIX_FMT_BGR4_BYTE,
-        PIX_FMT_YUV444P,      PIX_FMT_YUV422P,
-        PIX_FMT_YUV420P,      PIX_FMT_YUVJ420P,
-        PIX_FMT_YUV411P,      PIX_FMT_YUV410P,
-        PIX_FMT_YUVJ444P,     PIX_FMT_YUVJ422P,
-        PIX_FMT_YUV440P,      PIX_FMT_YUVJ440P,
-        PIX_FMT_YUVA420P,     PIX_FMT_GRAY8,
-        PIX_FMT_NONE
-    };
-
-    avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
-    return 0;
-}
-
 static int config_props_output(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
@@ -114,56 +84,10 @@ static void end_frame(AVFilterLink *inlink)
     AVFilterBufferRef *inpic  = inlink->cur_buf;
     AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf;
     AVFilterLink *outlink = inlink->dst->outputs[0];
-    int plane;
-
-    for (plane = 0; outpic->data[plane]; plane++) {
-        int hsub = plane == 1 || plane == 2 ? trans->hsub : 0;
-        int vsub = plane == 1 || plane == 2 ? trans->vsub : 0;
-        int pixstep = trans->pixsteps[plane];
-        int inh  = inpic->video->h>>vsub;
-        int outw = outpic->video->w>>hsub;
-        int outh = outpic->video->h>>vsub;
-        uint8_t *out, *in;
-        int outlinesize, inlinesize;
-        int x, y;
-
-        out = outpic->data[plane]; outlinesize = outpic->linesize[plane];
-        in  = inpic ->data[plane]; inlinesize  = inpic ->linesize[plane];
-
-        if (trans->dir&1) {
-            in +=  inpic->linesize[plane] * (inh-1);
-            inlinesize *= -1;
-        }
-
-        if (trans->dir&2) {
-            out += outpic->linesize[plane] * (outh-1);
-            outlinesize *= -1;
-        }
-
-        for (y = 0; y < outh; y++) {
-            switch (pixstep) {
-            case 1:
-                for (x = 0; x < outw; x++)
-                    *(out + x) = *(in + x*inlinesize + y);
-                break;
-            case 2:
-                for (x = 0; x < outw; x++)
-                    *((uint16_t *)(out + 2*x)) = *((uint16_t *)(in + x*inlinesize + y*2));
-                break;
-            case 3:
-                for (x = 0; x < outw; x++) {
-                    int32_t v = AV_RB24(in + x*inlinesize + y*3);
-                    AV_WB24(out + 3*x, v);
-                }
-                break;
-            case 4:
-                for (x = 0; x < outw; x++)
-                    *((uint32_t *)(out + 4*x)) = *((uint32_t *)(in + x*inlinesize + y*4));
-                break;
-            }
-            out += outlinesize;
-        }
-    }
+
+    ff_transpose(outpic->data, outpic->linesize, inpic->data, inpic->linesize,
+                 outpic->video->w, outpic->video->h, trans->pixsteps,
+                 trans->hsub, trans->vsub, trans->dir);
 
     avfilter_unref_buffer(inpic);
     avfilter_draw_slice(outlink, 0, outpic->video->h, 1);
@@ -196,7 +120,7 @@ AVFilter avfilter_vf_transpose = {
     .init = init,
     .priv_size = sizeof(TransContext),
 
-    .query_formats = query_formats,
+    .query_formats = ff_transpose_query_formats,
 
     .inputs    = (AVFilterPad[]) {{ .name            = "default",
                                     .type            = AVMEDIA_TYPE_VIDEO,
-- 
1.7.1




More information about the ffmpeg-devel mailing list