Browse code

avfilter/vf_stereo3d: add interleave columns output format

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

Paul B Mahol authored on 2015/09/06 17:50:14
Showing 1 changed files
... ...
@@ -62,6 +62,8 @@ enum StereoCode {
62 62
     ALTERNATING_RL,     // alternating frames (right eye first, left eye second)
63 63
     CHECKERBOARD_LR,    // checkerboard pattern (left eye first, right eye second)
64 64
     CHECKERBOARD_RL,    // checkerboard pattern (right eye first, left eye second)
65
+    INTERLEAVE_COLS_LR, // column-interleave (left eye first, right eye second)
66
+    INTERLEAVE_COLS_RL, // column-interleave (right eye first, left eye second)
65 67
     HDMI,               // HDMI frame pack (left eye first, right eye second)
66 68
     STEREO_CODE_COUNT   // TODO: needs autodetection
67 69
 };
... ...
@@ -198,6 +200,8 @@ static const AVOption stereo3d_options[] = {
198 198
     { "sbsr",  "side by side right first",            0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_RL},    0, 0, FLAGS, "out" },
199 199
     { "chl",   "checkerboard left first",             0, AV_OPT_TYPE_CONST, {.i64=CHECKERBOARD_LR},    0, 0, FLAGS, "out" },
200 200
     { "chr",   "checkerboard right first",            0, AV_OPT_TYPE_CONST, {.i64=CHECKERBOARD_RL},    0, 0, FLAGS, "out" },
201
+    { "icl",   "interleave columns left first",       0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_COLS_LR}, 0, 0, FLAGS, "out" },
202
+    { "icr",   "interleave columns right first",      0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_COLS_RL}, 0, 0, FLAGS, "out" },
201 203
     { "hdmi",  "HDMI frame pack",                     0, AV_OPT_TYPE_CONST, {.i64=HDMI},               0, 0, FLAGS, "out" },
202 204
     { NULL }
203 205
 };
... ...
@@ -496,6 +500,10 @@ static int config_output(AVFilterLink *outlink)
496 496
     case CHECKERBOARD_RL:
497 497
         s->out.width     = s->width * 2;
498 498
         break;
499
+    case INTERLEAVE_COLS_LR:
500
+    case INTERLEAVE_COLS_RL:
501
+        s->out.width     = s->width * 2;
502
+        break;
499 503
     default:
500 504
         av_log(ctx, AV_LOG_ERROR, "output format %d is not supported\n", s->out.format);
501 505
         return AVERROR(EINVAL);
... ...
@@ -743,6 +751,61 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
743 743
             }
744 744
         }
745 745
         break;
746
+    case INTERLEAVE_COLS_LR:
747
+    case INTERLEAVE_COLS_RL:
748
+        for (i = 0; i < s->nb_planes; i++) {
749
+            int x, y;
750
+
751
+            for (y = 0; y < s->pheight[i]; y++) {
752
+                uint8_t *dst = out->data[i] + out->linesize[i] * y;
753
+                uint8_t *left = ileft->data[i] + ileft->linesize[i] * y * s->in.row_step + s->in_off_left[i];
754
+                uint8_t *right = iright->data[i] + iright->linesize[i] * y * s->in.row_step + s->in_off_right[i];
755
+                int p, b;
756
+
757
+                if (s->out.format == INTERLEAVE_COLS_LR)
758
+                    FFSWAP(uint8_t*, left, right);
759
+
760
+                switch (s->pixstep[i]) {
761
+                case 1:
762
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=2, p++, b++) {
763
+                        dst[x  ] =   b&1  ? left[p] : right[p];
764
+                        dst[x+1] = !(b&1) ? left[p] : right[p];
765
+                    }
766
+                    break;
767
+                case 2:
768
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=4, p+=2, b++) {
769
+                        AV_WN16(&dst[x  ],   b&1  ? AV_RN16(&left[p]) : AV_RN16(&right[p]));
770
+                        AV_WN16(&dst[x+2], !(b&1) ? AV_RN16(&left[p]) : AV_RN16(&right[p]));
771
+                    }
772
+                    break;
773
+                case 3:
774
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=6, p+=3, b++) {
775
+                        AV_WB24(&dst[x  ],   b&1  ? AV_RB24(&left[p]) : AV_RB24(&right[p]));
776
+                        AV_WB24(&dst[x+3], !(b&1) ? AV_RB24(&left[p]) : AV_RB24(&right[p]));
777
+                    }
778
+                    break;
779
+                case 4:
780
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=8, p+=4, b++) {
781
+                        AV_WN32(&dst[x  ],   b&1  ? AV_RN32(&left[p]) : AV_RN32(&right[p]));
782
+                        AV_WN32(&dst[x+4], !(b&1) ? AV_RN32(&left[p]) : AV_RN32(&right[p]));
783
+                    }
784
+                    break;
785
+                case 6:
786
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=12, p+=6, b++) {
787
+                        AV_WB48(&dst[x  ],   b&1  ? AV_RB48(&left[p]) : AV_RB48(&right[p]));
788
+                        AV_WB48(&dst[x+6], !(b&1) ? AV_RB48(&left[p]) : AV_RB48(&right[p]));
789
+                    }
790
+                    break;
791
+                case 8:
792
+                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=16, p+=8, b++) {
793
+                        AV_WN64(&dst[x  ],   b&1 ?  AV_RN64(&left[p]) : AV_RN64(&right[p]));
794
+                        AV_WN64(&dst[x+8], !(b&1) ? AV_RN64(&left[p]) : AV_RN64(&right[p]));
795
+                    }
796
+                    break;
797
+                }
798
+            }
799
+        }
800
+        break;
746 801
     default:
747 802
         av_assert0(0);
748 803
     }