[FFmpeg-devel] [PATCH] avfilter/vf_stereo3d: add checkerboard output format

Paul B Mahol onemda at gmail.com
Thu Sep 3 13:52:52 CEST 2015


Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
 doc/filters.texi          |  6 ++++++
 libavfilter/vf_stereo3d.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 162958f..cdd73fc 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -9865,6 +9865,12 @@ mono output (left eye only)
 
 @item mr
 mono output (right eye only)
+
+ at item chl
+checkerboard, left eye first
+
+ at item chr
+checkerboard, right eye first
 @end table
 
 Default value is @samp{arcd}.
diff --git a/libavfilter/vf_stereo3d.c b/libavfilter/vf_stereo3d.c
index 5309d70..6e90e16 100644
--- a/libavfilter/vf_stereo3d.c
+++ b/libavfilter/vf_stereo3d.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2010 Gordon Schmidt <gordon.schmidt <at> s2000.tu-chemnitz.de>
- * Copyright (c) 2013 Paul B Mahol
+ * Copyright (c) 2013-2015 Paul B Mahol
  *
  * This file is part of FFmpeg.
  *
@@ -21,6 +21,7 @@
 
 #include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/pixdesc.h"
@@ -59,6 +60,8 @@ enum StereoCode {
     ABOVE_BELOW_2_RL,   // above-below with half height resolution
     ALTERNATING_LR,     // alternating frames (left eye first, right eye second)
     ALTERNATING_RL,     // alternating frames (right eye first, left eye second)
+    CHECKERBOARD_LR,    // checkerboard pattern (left eye first, right eye second)
+    CHECKERBOARD_RL,    // checkerboard pattern (right eye first, left eye second)
     STEREO_CODE_COUNT   // TODO: needs autodetection
 };
 
@@ -189,6 +192,8 @@ static const AVOption stereo3d_options[] = {
     { "sbs2r", "side by side half width right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_RL},  0, 0, FLAGS, "out" },
     { "sbsl",  "side by side left first",             0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_LR},    0, 0, FLAGS, "out" },
     { "sbsr",  "side by side right first",            0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_RL},    0, 0, FLAGS, "out" },
+    { "chl",   "checkerboard left first",             0, AV_OPT_TYPE_CONST, {.i64=CHECKERBOARD_LR},    0, 0, FLAGS, "out" },
+    { "chr",   "checkerboard right first",            0, AV_OPT_TYPE_CONST, {.i64=CHECKERBOARD_RL},    0, 0, FLAGS, "out" },
     { NULL }
 };
 
@@ -451,6 +456,9 @@ static int config_output(AVFilterLink *outlink)
         fps.num         *= 2;
         tb.den          *= 2;
         break;
+    case CHECKERBOARD_LR:
+    case CHECKERBOARD_RL:
+        break;
     default:
         av_log(ctx, AV_LOG_ERROR, "output format %d is not supported\n", s->out.format);
         return AVERROR(EINVAL);
@@ -633,6 +641,46 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
                                FFMIN(s->out.height, ctx->graph->nb_threads));
         break;
     }
+    case CHECKERBOARD_RL:
+    case CHECKERBOARD_LR:
+        for (i = 0; i < s->nb_planes; i++) {
+            int x, y;
+
+            for (y = 0; y < s->pheight[i]; y++) {
+                uint8_t *dst = out->data[i] + out->linesize[i] * y;
+                uint8_t *left = ileft->data[i] + ileft->linesize[i] * y + s->in_off_left[i];
+                uint8_t *right = iright->data[i] + iright->linesize[i] * y + s->in_off_right[i];
+
+                if (s->out.format == CHECKERBOARD_RL)
+                    FFSWAP(uint8_t*, left, right);
+                switch (s->pixstep[i]) {
+                case 1:
+                    for (x = 0; x < s->linesize[i]; x+=s->pixstep[i])
+                        dst[x] = (x&1) == (y&1) ? left[x] : right[x];
+                    break;
+                case 2:
+                    for (x = 0; x < s->linesize[i]; x+=s->pixstep[i])
+                        AV_WN16(&dst[x], (x&1) == (y&1) ? AV_RN16(&left[x]) : AV_RN16(&right[x]));
+                case 3:
+                    for (x = 0; x < s->linesize[i]; x+=s->pixstep[i])
+                        AV_WB24(&dst[x], (x&1) == (y&1) ? AV_RB24(&left[x]) : AV_RB24(&right[x]));
+                    break;
+                case 4:
+                    for (x = 0; x < s->linesize[i]; x+=s->pixstep[i])
+                        AV_WN32(&dst[x], (x&1) == (y&1) ? AV_RN32(&left[x]) : AV_RN32(&right[x]));
+                    break;
+                case 6:
+                    for (x = 0; x < s->linesize[i]; x+=s->pixstep[i])
+                        AV_WB48(&dst[x], (x&1) == (y&1) ? AV_RB48(&left[x]) : AV_RB48(&right[x]));
+                    break;
+                case 8:
+                    for (x = 0; x < s->linesize[i]; x+=s->pixstep[i])
+                        AV_WN64(&dst[x], (x&1) == (y&1) ? AV_RN64(&left[x]) : AV_RN64(&right[x]));
+                    break;
+                }
+            }
+        }
+        break;
     default:
         av_assert0(0);
     }
-- 
1.7.11.2



More information about the ffmpeg-devel mailing list