Browse code

avfilter/vf_stereo3d: support interleaved rows as input format

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

Paul B Mahol authored on 2015/09/05 09:05:50
Showing 1 changed files
... ...
@@ -71,6 +71,7 @@ typedef struct StereoComponent {
71 71
     int off_left, off_right;
72 72
     int off_lstep, off_rstep;
73 73
     int row_left, row_right;
74
+    int row_step;
74 75
 } StereoComponent;
75 76
 
76 77
 static const int ana_coeff[][3][6] = {
... ...
@@ -136,7 +137,6 @@ typedef struct Stereo3DContext {
136 136
     const AVClass *class;
137 137
     StereoComponent in, out;
138 138
     int width, height;
139
-    int row_step;
140 139
     const int *ana_matrix[3];
141 140
     int nb_planes;
142 141
     int linesize[4];
... ...
@@ -152,18 +152,20 @@ typedef struct Stereo3DContext {
152 152
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
153 153
 
154 154
 static const AVOption stereo3d_options[] = {
155
-    { "in",    "set input format",  OFFSET(in.format),  AV_OPT_TYPE_INT, {.i64=SIDE_BY_SIDE_LR}, SIDE_BY_SIDE_LR, STEREO_CODE_COUNT-1, FLAGS, "in"},
156
-    { "ab2l",  "above below half height left first",  0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR},  0, 0, FLAGS, "in" },
157
-    { "ab2r",  "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL},  0, 0, FLAGS, "in" },
158
-    { "abl",   "above below left first",              0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR},    0, 0, FLAGS, "in" },
159
-    { "abr",   "above below right first",             0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_RL},    0, 0, FLAGS, "in" },
160
-    { "al",    "alternating frames left first",       0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_LR},    0, 0, FLAGS, "in" },
161
-    { "ar",    "alternating frames right first",      0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_RL},    0, 0, FLAGS, "in" },
162
-    { "sbs2l", "side by side half width left first",  0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_LR}, 0, 0, FLAGS, "in" },
163
-    { "sbs2r", "side by side half width right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_RL}, 0, 0, FLAGS, "in" },
164
-    { "sbsl",  "side by side left first",             0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_LR},   0, 0, FLAGS, "in" },
165
-    { "sbsr",  "side by side right first",            0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_RL},   0, 0, FLAGS, "in" },
166
-    { "out",   "set output format", OFFSET(out.format), AV_OPT_TYPE_INT, {.i64=ANAGLYPH_RC_DUBOIS}, 0, STEREO_CODE_COUNT-1, FLAGS, "out"},
155
+    { "in",    "set input format",  OFFSET(in.format),   AV_OPT_TYPE_INT,   {.i64=SIDE_BY_SIDE_LR}, INTERLEAVE_ROWS_LR, STEREO_CODE_COUNT-1, FLAGS, "in"},
156
+    { "ab2l",  "above below half height left first",  0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR},   0, 0, FLAGS, "in" },
157
+    { "ab2r",  "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL},   0, 0, FLAGS, "in" },
158
+    { "abl",   "above below left first",              0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR},     0, 0, FLAGS, "in" },
159
+    { "abr",   "above below right first",             0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_RL},     0, 0, FLAGS, "in" },
160
+    { "al",    "alternating frames left first",       0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_LR},     0, 0, FLAGS, "in" },
161
+    { "ar",    "alternating frames right first",      0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_RL},     0, 0, FLAGS, "in" },
162
+    { "sbs2l", "side by side half width left first",  0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_LR},  0, 0, FLAGS, "in" },
163
+    { "sbs2r", "side by side half width right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_RL},  0, 0, FLAGS, "in" },
164
+    { "sbsl",  "side by side left first",             0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_LR},    0, 0, FLAGS, "in" },
165
+    { "sbsr",  "side by side right first",            0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_RL},    0, 0, FLAGS, "in" },
166
+    { "irl",   "interleave rows left first",          0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_ROWS_LR}, 0, 0, FLAGS, "in" },
167
+    { "irr",   "interleave rows right first",         0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_ROWS_RL}, 0, 0, FLAGS, "in" },
168
+    { "out",   "set output format", OFFSET(out.format),  AV_OPT_TYPE_INT,   {.i64=ANAGLYPH_RC_DUBOIS}, 0, STEREO_CODE_COUNT-1, FLAGS, "out"},
167 169
     { "ab2l",  "above below half height left first",  0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR},   0, 0, FLAGS, "out" },
168 170
     { "ab2r",  "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL},   0, 0, FLAGS, "out" },
169 171
     { "abl",   "above below left first",              0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR},     0, 0, FLAGS, "out" },
... ...
@@ -312,6 +314,8 @@ static int config_output(AVFilterLink *outlink)
312 312
             return AVERROR_INVALIDDATA;
313 313
         }
314 314
         break;
315
+    case INTERLEAVE_ROWS_LR:
316
+    case INTERLEAVE_ROWS_RL:
315 317
     case ABOVE_BELOW_2_LR:
316 318
     case ABOVE_BELOW_LR:
317 319
     case ABOVE_BELOW_2_RL:
... ...
@@ -334,13 +338,13 @@ static int config_output(AVFilterLink *outlink)
334 334
     s->width        = inlink->w;
335 335
     s->in.height    =
336 336
     s->height       = inlink->h;
337
-    s->row_step     = 1;
338 337
     s->in.off_lstep =
339 338
     s->in.off_rstep =
340 339
     s->in.off_left  =
341 340
     s->in.off_right =
342 341
     s->in.row_left  =
343 342
     s->in.row_right = 0;
343
+    s->in.row_step  = 1;
344 344
 
345 345
     switch (s->in.format) {
346 346
     case SIDE_BY_SIDE_2_LR:
... ...
@@ -373,6 +377,19 @@ static int config_output(AVFilterLink *outlink)
373 373
         fps.den        *= 2;
374 374
         tb.num         *= 2;
375 375
         break;
376
+    case INTERLEAVE_ROWS_LR:
377
+    case INTERLEAVE_ROWS_RL:
378
+        s->in.row_step  = 2;
379
+        if (s->in.format == INTERLEAVE_ROWS_RL)
380
+            s->in.off_lstep = 1;
381
+        else
382
+            s->in.off_rstep = 1;
383
+        if (s->out.format != INTERLEAVE_ROWS_LR &&
384
+            s->out.format != INTERLEAVE_ROWS_RL &&
385
+            s->out.format != CHECKERBOARD_LR &&
386
+            s->out.format != CHECKERBOARD_RL)
387
+            s->height   = inlink->h / 2;
388
+        break;
376 389
     default:
377 390
         av_log(ctx, AV_LOG_ERROR, "input format %d is not supported\n", s->in.format);
378 391
         return AVERROR(EINVAL);
... ...
@@ -386,6 +403,7 @@ static int config_output(AVFilterLink *outlink)
386 386
     s->out.off_right =
387 387
     s->out.row_left  =
388 388
     s->out.row_right = 0;
389
+    s->out.row_step  = 1;
389 390
 
390 391
     switch (s->out.format) {
391 392
     case ANAGLYPH_RB_GRAY:
... ...
@@ -435,21 +453,28 @@ static int config_output(AVFilterLink *outlink)
435 435
         s->out.row_left  = s->height;
436 436
         break;
437 437
     case INTERLEAVE_ROWS_LR:
438
-        s->row_step      = 2;
438
+        s->in.row_step   = 2;
439
+        s->out.row_step  = 2;
439 440
         s->height        = s->height / 2;
440
-        s->out.off_rstep =
441
-        s->in.off_rstep  = 1;
441
+        s->out.off_rstep = 1;
442
+        s->in.off_rstep  = s->in.format != INTERLEAVE_ROWS_RL;
442 443
         break;
443 444
     case INTERLEAVE_ROWS_RL:
444
-        s->row_step      = 2;
445
+        s->in.row_step   = 2;
446
+        s->out.row_step  = 2;
445 447
         s->height        = s->height / 2;
446
-        s->out.off_lstep =
447
-        s->in.off_lstep  = 1;
448
+        s->out.off_lstep = 1;
449
+        s->in.off_lstep  = s->in.format != INTERLEAVE_ROWS_LR;
448 450
         break;
449 451
     case MONO_R:
450 452
         s->in.off_left   = s->in.off_right;
451 453
         s->in.row_left   = s->in.row_right;
454
+        if (s->in.format == INTERLEAVE_ROWS_LR)
455
+            FFSWAP(int, s->in.off_lstep, s->in.off_rstep);
456
+        break;
452 457
     case MONO_L:
458
+        if (s->in.format == INTERLEAVE_ROWS_RL)
459
+            FFSWAP(int, s->in.off_lstep, s->in.off_rstep);
453 460
         break;
454 461
     case ALTERNATING_RL:
455 462
     case ALTERNATING_LR:
... ...
@@ -519,8 +544,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
519 519
 
520 520
     for (y = start; y < end; y++) {
521 521
         o   = out->linesize[0] * y;
522
-        il  = s->in_off_left[0]  + y * ileft->linesize[0];
523
-        ir  = s->in_off_right[0] + y * iright->linesize[0];
522
+        il  = s->in_off_left[0]  + y * ileft->linesize[0] * s->in.row_step;
523
+        ir  = s->in_off_right[0] + y * iright->linesize[0] * s->in.row_step;
524 524
         for (x = 0; x < out_width; x++, il += 3, ir += 3, o+= 3) {
525 525
             dst[o    ] = ana_convert(ana_matrix[0], lsrc + il, rsrc + ir);
526 526
             dst[o + 1] = ana_convert(ana_matrix[1], lsrc + il, rsrc + ir);
... ...
@@ -540,6 +565,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
540 540
     int out_off_left[4], out_off_right[4];
541 541
     int i;
542 542
 
543
+    if (s->in.format == s->out.format)
544
+        return ff_filter_frame(outlink, inpicref);
545
+
543 546
     switch (s->in.format) {
544 547
     case ALTERNATING_LR:
545 548
     case ALTERNATING_RL:
... ...
@@ -600,14 +628,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
600 600
     case INTERLEAVE_ROWS_RL:
601 601
         for (i = 0; i < s->nb_planes; i++) {
602 602
             av_image_copy_plane(oleft->data[i] + out_off_left[i],
603
-                                oleft->linesize[i] * s->row_step,
603
+                                oleft->linesize[i] * s->out.row_step,
604 604
                                 ileft->data[i] + s->in_off_left[i],
605
-                                ileft->linesize[i] * s->row_step,
605
+                                ileft->linesize[i] * s->in.row_step,
606 606
                                 s->linesize[i], s->pheight[i]);
607 607
             av_image_copy_plane(oright->data[i] + out_off_right[i],
608
-                                oright->linesize[i] * s->row_step,
608
+                                oright->linesize[i] * s->out.row_step,
609 609
                                 iright->data[i] + s->in_off_right[i],
610
-                                iright->linesize[i] * s->row_step,
610
+                                iright->linesize[i] * s->in.row_step,
611 611
                                 s->linesize[i], s->pheight[i]);
612 612
         }
613 613
         break;
... ...
@@ -617,7 +645,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
617 617
         for (i = 0; i < s->nb_planes; i++) {
618 618
             av_image_copy_plane(out->data[i], out->linesize[i],
619 619
                                 iright->data[i] + s->in_off_left[i],
620
-                                iright->linesize[i],
620
+                                iright->linesize[i] * s->in.row_step,
621 621
                                 s->linesize[i], s->pheight[i]);
622 622
         }
623 623
         break;