Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2015/09/05 09:05:50... | ... |
@@ -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; |