Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2015/07/10 04:18:14... | ... |
@@ -142,6 +142,7 @@ typedef struct Stereo3DContext { |
142 | 142 |
int pixstep[4]; |
143 | 143 |
AVFrame *prev; |
144 | 144 |
double ts_unit; |
145 |
+ int in_off_left[4], in_off_right[4]; |
|
145 | 146 |
} Stereo3DContext; |
146 | 147 |
|
147 | 148 |
#define OFFSET(x) offsetof(Stereo3DContext, x) |
... | ... |
@@ -485,6 +486,42 @@ static inline uint8_t ana_convert(const int *coeff, const uint8_t *left, const u |
485 | 485 |
return av_clip_uint8(sum >> 16); |
486 | 486 |
} |
487 | 487 |
|
488 |
+typedef struct ThreadData { |
|
489 |
+ AVFrame *ileft, *iright; |
|
490 |
+ AVFrame *out; |
|
491 |
+} ThreadData; |
|
492 |
+ |
|
493 |
+static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) |
|
494 |
+{ |
|
495 |
+ Stereo3DContext *s = ctx->priv; |
|
496 |
+ ThreadData *td = arg; |
|
497 |
+ AVFrame *ileft = td->ileft; |
|
498 |
+ AVFrame *iright = td->iright; |
|
499 |
+ AVFrame *out = td->out; |
|
500 |
+ int height = s->out.height; |
|
501 |
+ int start = (height * jobnr ) / nb_jobs; |
|
502 |
+ int end = (height * (jobnr+1)) / nb_jobs; |
|
503 |
+ uint8_t *dst = out->data[0]; |
|
504 |
+ const int **ana_matrix = s->ana_matrix; |
|
505 |
+ int x, y, il, ir, o; |
|
506 |
+ const uint8_t *lsrc = ileft->data[0]; |
|
507 |
+ const uint8_t *rsrc = iright->data[0]; |
|
508 |
+ int out_width = s->out.width; |
|
509 |
+ |
|
510 |
+ for (y = start; y < end; y++) { |
|
511 |
+ o = out->linesize[0] * y; |
|
512 |
+ il = s->in_off_left[0] + y * ileft->linesize[0]; |
|
513 |
+ ir = s->in_off_right[0] + y * iright->linesize[0]; |
|
514 |
+ for (x = 0; x < out_width; x++, il += 3, ir += 3, o+= 3) { |
|
515 |
+ dst[o ] = ana_convert(ana_matrix[0], lsrc + il, rsrc + ir); |
|
516 |
+ dst[o + 1] = ana_convert(ana_matrix[1], lsrc + il, rsrc + ir); |
|
517 |
+ dst[o + 2] = ana_convert(ana_matrix[2], lsrc + il, rsrc + ir); |
|
518 |
+ } |
|
519 |
+ } |
|
520 |
+ |
|
521 |
+ return 0; |
|
522 |
+} |
|
523 |
+ |
|
488 | 524 |
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) |
489 | 525 |
{ |
490 | 526 |
AVFilterContext *ctx = inlink->dst; |
... | ... |
@@ -492,7 +529,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) |
492 | 492 |
AVFilterLink *outlink = ctx->outputs[0]; |
493 | 493 |
AVFrame *out, *oleft, *oright, *ileft, *iright; |
494 | 494 |
int out_off_left[4], out_off_right[4]; |
495 |
- int in_off_left[4], in_off_right[4]; |
|
496 | 495 |
int i; |
497 | 496 |
|
498 | 497 |
switch (s->in.format) { |
... | ... |
@@ -534,8 +570,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) |
534 | 534 |
for (i = 0; i < 4; i++) { |
535 | 535 |
int hsub = i == 1 || i == 2 ? s->hsub : 0; |
536 | 536 |
int vsub = i == 1 || i == 2 ? s->vsub : 0; |
537 |
- in_off_left[i] = (FF_CEIL_RSHIFT(s->in.row_left, vsub) + s->in.off_lstep) * ileft->linesize[i] + FF_CEIL_RSHIFT(s->in.off_left * s->pixstep[i], hsub); |
|
538 |
- in_off_right[i] = (FF_CEIL_RSHIFT(s->in.row_right, vsub) + s->in.off_rstep) * iright->linesize[i] + FF_CEIL_RSHIFT(s->in.off_right * s->pixstep[i], hsub); |
|
537 |
+ s->in_off_left[i] = (FF_CEIL_RSHIFT(s->in.row_left, vsub) + s->in.off_lstep) * ileft->linesize[i] + FF_CEIL_RSHIFT(s->in.off_left * s->pixstep[i], hsub); |
|
538 |
+ s->in_off_right[i] = (FF_CEIL_RSHIFT(s->in.row_right, vsub) + s->in.off_rstep) * iright->linesize[i] + FF_CEIL_RSHIFT(s->in.off_right * s->pixstep[i], hsub); |
|
539 | 539 |
out_off_left[i] = (FF_CEIL_RSHIFT(s->out.row_left, vsub) + s->out.off_lstep) * oleft->linesize[i] + FF_CEIL_RSHIFT(s->out.off_left * s->pixstep[i], hsub); |
540 | 540 |
out_off_right[i] = (FF_CEIL_RSHIFT(s->out.row_right, vsub) + s->out.off_rstep) * oright->linesize[i] + FF_CEIL_RSHIFT(s->out.off_right * s->pixstep[i], hsub); |
541 | 541 |
} |
... | ... |
@@ -556,12 +592,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) |
556 | 556 |
for (i = 0; i < s->nb_planes; i++) { |
557 | 557 |
av_image_copy_plane(oleft->data[i] + out_off_left[i], |
558 | 558 |
oleft->linesize[i] * s->row_step, |
559 |
- ileft->data[i] + in_off_left[i], |
|
559 |
+ ileft->data[i] + s->in_off_left[i], |
|
560 | 560 |
ileft->linesize[i] * s->row_step, |
561 | 561 |
s->linesize[i], s->pheight[i]); |
562 | 562 |
av_image_copy_plane(oright->data[i] + out_off_right[i], |
563 | 563 |
oright->linesize[i] * s->row_step, |
564 |
- iright->data[i] + in_off_right[i], |
|
564 |
+ iright->data[i] + s->in_off_right[i], |
|
565 | 565 |
iright->linesize[i] * s->row_step, |
566 | 566 |
s->linesize[i], s->pheight[i]); |
567 | 567 |
} |
... | ... |
@@ -571,7 +607,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) |
571 | 571 |
case MONO_R: |
572 | 572 |
for (i = 0; i < s->nb_planes; i++) { |
573 | 573 |
av_image_copy_plane(out->data[i], out->linesize[i], |
574 |
- iright->data[i] + in_off_left[i], |
|
574 |
+ iright->data[i] + s->in_off_left[i], |
|
575 | 575 |
iright->linesize[i], |
576 | 576 |
s->linesize[i], s->pheight[i]); |
577 | 577 |
} |
... | ... |
@@ -590,23 +626,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) |
590 | 590 |
case ANAGLYPH_YB_HALF: |
591 | 591 |
case ANAGLYPH_YB_COLOR: |
592 | 592 |
case ANAGLYPH_YB_DUBOIS: { |
593 |
- int x, y, il, ir, o; |
|
594 |
- const uint8_t *lsrc = ileft->data[0]; |
|
595 |
- const uint8_t *rsrc = iright->data[0]; |
|
596 |
- uint8_t *dst = out->data[0]; |
|
597 |
- int out_width = s->out.width; |
|
598 |
- const int **ana_matrix = s->ana_matrix; |
|
599 |
- |
|
600 |
- for (y = 0; y < s->out.height; y++) { |
|
601 |
- o = out->linesize[0] * y; |
|
602 |
- il = in_off_left[0] + y * ileft->linesize[0]; |
|
603 |
- ir = in_off_right[0] + y * iright->linesize[0]; |
|
604 |
- for (x = 0; x < out_width; x++, il += 3, ir += 3, o+= 3) { |
|
605 |
- dst[o ] = ana_convert(ana_matrix[0], lsrc + il, rsrc + ir); |
|
606 |
- dst[o + 1] = ana_convert(ana_matrix[1], lsrc + il, rsrc + ir); |
|
607 |
- dst[o + 2] = ana_convert(ana_matrix[2], lsrc + il, rsrc + ir); |
|
608 |
- } |
|
609 |
- } |
|
593 |
+ ThreadData td; |
|
594 |
+ |
|
595 |
+ td.ileft = ileft; td.iright = iright; td.out = out; |
|
596 |
+ ctx->internal->execute(ctx, filter_slice, &td, NULL, |
|
597 |
+ FFMIN(s->out.height, ctx->graph->nb_threads)); |
|
610 | 598 |
break; |
611 | 599 |
} |
612 | 600 |
default: |
... | ... |
@@ -663,4 +687,5 @@ AVFilter ff_vf_stereo3d = { |
663 | 663 |
.inputs = stereo3d_inputs, |
664 | 664 |
.outputs = stereo3d_outputs, |
665 | 665 |
.priv_class = &stereo3d_class, |
666 |
+ .flags = AVFILTER_FLAG_SLICE_THREADS, |
|
666 | 667 |
}; |