Browse code

avfilter/vf_stereo3d: add checkerboard output format

Signed-off-by: Paul B Mahol <onemda@gmail.com>

Paul B Mahol authored on 2015/09/03 20:49:59
Showing 2 changed files
... ...
@@ -9891,6 +9891,12 @@ mono output (left eye only)
9891 9891
 
9892 9892
 @item mr
9893 9893
 mono output (right eye only)
9894
+
9895
+@item chl
9896
+checkerboard, left eye first
9897
+
9898
+@item chr
9899
+checkerboard, right eye first
9894 9900
 @end table
9895 9901
 
9896 9902
 Default value is @samp{arcd}.
... ...
@@ -1,6 +1,6 @@
1 1
 /*
2 2
  * Copyright (c) 2010 Gordon Schmidt <gordon.schmidt <at> s2000.tu-chemnitz.de>
3
- * Copyright (c) 2013 Paul B Mahol
3
+ * Copyright (c) 2013-2015 Paul B Mahol
4 4
  *
5 5
  * This file is part of FFmpeg.
6 6
  *
... ...
@@ -21,6 +21,7 @@
21 21
 
22 22
 #include "libavutil/avassert.h"
23 23
 #include "libavutil/imgutils.h"
24
+#include "libavutil/intreadwrite.h"
24 25
 #include "libavutil/opt.h"
25 26
 #include "libavutil/parseutils.h"
26 27
 #include "libavutil/pixdesc.h"
... ...
@@ -59,6 +60,8 @@ enum StereoCode {
59 59
     ABOVE_BELOW_2_RL,   // above-below with half height resolution
60 60
     ALTERNATING_LR,     // alternating frames (left eye first, right eye second)
61 61
     ALTERNATING_RL,     // alternating frames (right eye first, left eye second)
62
+    CHECKERBOARD_LR,    // checkerboard pattern (left eye first, right eye second)
63
+    CHECKERBOARD_RL,    // checkerboard pattern (right eye first, left eye second)
62 64
     STEREO_CODE_COUNT   // TODO: needs autodetection
63 65
 };
64 66
 
... ...
@@ -189,6 +192,8 @@ static const AVOption stereo3d_options[] = {
189 189
     { "sbs2r", "side by side half width right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_RL},  0, 0, FLAGS, "out" },
190 190
     { "sbsl",  "side by side left first",             0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_LR},    0, 0, FLAGS, "out" },
191 191
     { "sbsr",  "side by side right first",            0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_RL},    0, 0, FLAGS, "out" },
192
+    { "chl",   "checkerboard left first",             0, AV_OPT_TYPE_CONST, {.i64=CHECKERBOARD_LR},    0, 0, FLAGS, "out" },
193
+    { "chr",   "checkerboard right first",            0, AV_OPT_TYPE_CONST, {.i64=CHECKERBOARD_RL},    0, 0, FLAGS, "out" },
192 194
     { NULL }
193 195
 };
194 196
 
... ...
@@ -451,6 +456,10 @@ static int config_output(AVFilterLink *outlink)
451 451
         fps.num         *= 2;
452 452
         tb.den          *= 2;
453 453
         break;
454
+    case CHECKERBOARD_LR:
455
+    case CHECKERBOARD_RL:
456
+        s->out.width     = s->width * 2;
457
+        break;
454 458
     default:
455 459
         av_log(ctx, AV_LOG_ERROR, "output format %d is not supported\n", s->out.format);
456 460
         return AVERROR(EINVAL);
... ...
@@ -633,6 +642,60 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
633 633
                                FFMIN(s->out.height, ctx->graph->nb_threads));
634 634
         break;
635 635
     }
636
+    case CHECKERBOARD_RL:
637
+    case CHECKERBOARD_LR:
638
+        for (i = 0; i < s->nb_planes; i++) {
639
+            int x, y;
640
+
641
+            for (y = 0; y < s->pheight[i]; y++) {
642
+                uint8_t *dst = out->data[i] + out->linesize[i] * y;
643
+                uint8_t *left = ileft->data[i] + ileft->linesize[i] * y + s->in_off_left[i];
644
+                uint8_t *right = iright->data[i] + iright->linesize[i] * y + s->in_off_right[i];
645
+                int p, b;
646
+
647
+                if (s->out.format == CHECKERBOARD_RL)
648
+                    FFSWAP(uint8_t*, left, right);
649
+                switch (s->pixstep[i]) {
650
+                case 1:
651
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=2, p++, b++) {
652
+                        dst[x  ] = (b&1) == (y&1) ? left[p] : right[p];
653
+                        dst[x+1] = (b&1) != (y&1) ? left[p] : right[p];
654
+                    }
655
+                    break;
656
+                case 2:
657
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=4, p+=2, b++) {
658
+                        AV_WN16(&dst[x  ], (b&1) == (y&1) ? AV_RN16(&left[p]) : AV_RN16(&right[p]));
659
+                        AV_WN16(&dst[x+2], (b&1) != (y&1) ? AV_RN16(&left[p]) : AV_RN16(&right[p]));
660
+                    }
661
+                    break;
662
+                case 3:
663
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=6, p+=3, b++) {
664
+                        AV_WB24(&dst[x  ], (b&1) == (y&1) ? AV_RB24(&left[p]) : AV_RB24(&right[p]));
665
+                        AV_WB24(&dst[x+3], (b&1) != (y&1) ? AV_RB24(&left[p]) : AV_RB24(&right[p]));
666
+                    }
667
+                    break;
668
+                case 4:
669
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=8, p+=4, b++) {
670
+                        AV_WN32(&dst[x  ], (b&1) == (y&1) ? AV_RN32(&left[p]) : AV_RN32(&right[p]));
671
+                        AV_WN32(&dst[x+4], (b&1) != (y&1) ? AV_RN32(&left[p]) : AV_RN32(&right[p]));
672
+                    }
673
+                    break;
674
+                case 6:
675
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=12, p+=6, b++) {
676
+                        AV_WB48(&dst[x  ], (b&1) == (y&1) ? AV_RB48(&left[p]) : AV_RB48(&right[p]));
677
+                        AV_WB48(&dst[x+6], (b&1) != (y&1) ? AV_RB48(&left[p]) : AV_RB48(&right[p]));
678
+                    }
679
+                    break;
680
+                case 8:
681
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=16, p+=8, b++) {
682
+                        AV_WN64(&dst[x  ], (b&1) == (y&1) ? AV_RN64(&left[p]) : AV_RN64(&right[p]));
683
+                        AV_WN64(&dst[x+8], (b&1) != (y&1) ? AV_RN64(&left[p]) : AV_RN64(&right[p]));
684
+                    }
685
+                    break;
686
+                }
687
+            }
688
+        }
689
+        break;
636 690
     default:
637 691
         av_assert0(0);
638 692
     }