summaryrefslogtreecommitdiff
path: root/libavfilter/vf_stereo3d.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2015-07-09 19:18:14 +0000
committerPaul B Mahol <onemda@gmail.com>2015-07-12 20:05:56 +0000
commit7b07e72abc031db5c7060c5e7f5cadebf0199406 (patch)
tree1055cf13a7e0eb9f5f31275ce1c231962ff524d6 /libavfilter/vf_stereo3d.c
parentc02ee69be9c511c16ecd07060f40f5c81300ed2f (diff)
avfilter/vf_stereo3d: implement slice threading for anaglyph output
Signed-off-by: Paul B Mahol <onemda@gmail.com>
Diffstat (limited to 'libavfilter/vf_stereo3d.c')
-rw-r--r--libavfilter/vf_stereo3d.c71
1 files changed, 48 insertions, 23 deletions
diff --git a/libavfilter/vf_stereo3d.c b/libavfilter/vf_stereo3d.c
index 771bdde676..5309d70d76 100644
--- a/libavfilter/vf_stereo3d.c
+++ b/libavfilter/vf_stereo3d.c
@@ -142,6 +142,7 @@ typedef struct Stereo3DContext {
int pixstep[4];
AVFrame *prev;
double ts_unit;
+ int in_off_left[4], in_off_right[4];
} Stereo3DContext;
#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
return av_clip_uint8(sum >> 16);
}
+typedef struct ThreadData {
+ AVFrame *ileft, *iright;
+ AVFrame *out;
+} ThreadData;
+
+static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+ Stereo3DContext *s = ctx->priv;
+ ThreadData *td = arg;
+ AVFrame *ileft = td->ileft;
+ AVFrame *iright = td->iright;
+ AVFrame *out = td->out;
+ int height = s->out.height;
+ int start = (height * jobnr ) / nb_jobs;
+ int end = (height * (jobnr+1)) / nb_jobs;
+ uint8_t *dst = out->data[0];
+ const int **ana_matrix = s->ana_matrix;
+ int x, y, il, ir, o;
+ const uint8_t *lsrc = ileft->data[0];
+ const uint8_t *rsrc = iright->data[0];
+ int out_width = s->out.width;
+
+ for (y = start; y < end; y++) {
+ o = out->linesize[0] * y;
+ il = s->in_off_left[0] + y * ileft->linesize[0];
+ ir = s->in_off_right[0] + y * iright->linesize[0];
+ for (x = 0; x < out_width; x++, il += 3, ir += 3, o+= 3) {
+ dst[o ] = ana_convert(ana_matrix[0], lsrc + il, rsrc + ir);
+ dst[o + 1] = ana_convert(ana_matrix[1], lsrc + il, rsrc + ir);
+ dst[o + 2] = ana_convert(ana_matrix[2], lsrc + il, rsrc + ir);
+ }
+ }
+
+ return 0;
+}
+
static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
{
AVFilterContext *ctx = inlink->dst;
@@ -492,7 +529,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
AVFilterLink *outlink = ctx->outputs[0];
AVFrame *out, *oleft, *oright, *ileft, *iright;
int out_off_left[4], out_off_right[4];
- int in_off_left[4], in_off_right[4];
int i;
switch (s->in.format) {
@@ -534,8 +570,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
for (i = 0; i < 4; i++) {
int hsub = i == 1 || i == 2 ? s->hsub : 0;
int vsub = i == 1 || i == 2 ? s->vsub : 0;
- 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);
- 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);
+ 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);
+ 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);
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);
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);
}
@@ -556,12 +592,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
for (i = 0; i < s->nb_planes; i++) {
av_image_copy_plane(oleft->data[i] + out_off_left[i],
oleft->linesize[i] * s->row_step,
- ileft->data[i] + in_off_left[i],
+ ileft->data[i] + s->in_off_left[i],
ileft->linesize[i] * s->row_step,
s->linesize[i], s->pheight[i]);
av_image_copy_plane(oright->data[i] + out_off_right[i],
oright->linesize[i] * s->row_step,
- iright->data[i] + in_off_right[i],
+ iright->data[i] + s->in_off_right[i],
iright->linesize[i] * s->row_step,
s->linesize[i], s->pheight[i]);
}
@@ -571,7 +607,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
case MONO_R:
for (i = 0; i < s->nb_planes; i++) {
av_image_copy_plane(out->data[i], out->linesize[i],
- iright->data[i] + in_off_left[i],
+ iright->data[i] + s->in_off_left[i],
iright->linesize[i],
s->linesize[i], s->pheight[i]);
}
@@ -590,23 +626,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
case ANAGLYPH_YB_HALF:
case ANAGLYPH_YB_COLOR:
case ANAGLYPH_YB_DUBOIS: {
- int x, y, il, ir, o;
- const uint8_t *lsrc = ileft->data[0];
- const uint8_t *rsrc = iright->data[0];
- uint8_t *dst = out->data[0];
- int out_width = s->out.width;
- const int **ana_matrix = s->ana_matrix;
-
- for (y = 0; y < s->out.height; y++) {
- o = out->linesize[0] * y;
- il = in_off_left[0] + y * ileft->linesize[0];
- ir = in_off_right[0] + y * iright->linesize[0];
- for (x = 0; x < out_width; x++, il += 3, ir += 3, o+= 3) {
- dst[o ] = ana_convert(ana_matrix[0], lsrc + il, rsrc + ir);
- dst[o + 1] = ana_convert(ana_matrix[1], lsrc + il, rsrc + ir);
- dst[o + 2] = ana_convert(ana_matrix[2], lsrc + il, rsrc + ir);
- }
- }
+ ThreadData td;
+
+ td.ileft = ileft; td.iright = iright; td.out = out;
+ ctx->internal->execute(ctx, filter_slice, &td, NULL,
+ FFMIN(s->out.height, ctx->graph->nb_threads));
break;
}
default:
@@ -663,4 +687,5 @@ AVFilter ff_vf_stereo3d = {
.inputs = stereo3d_inputs,
.outputs = stereo3d_outputs,
.priv_class = &stereo3d_class,
+ .flags = AVFILTER_FLAG_SLICE_THREADS,
};