Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Bœsch <u@pkh.me>2014-02-13 17:34:58 +0400
committerClément Bœsch <u@pkh.me>2014-02-13 17:35:10 +0400
commit0e97ec54dea9330041f8a7ed30e4cd9a53c60e11 (patch)
treee703a383024bdd4d4a50807ad8026869884b0f53 /libavfilter/vf_curves.c
parent842b6c14bcfc1c5da1a2d288fd65386eb8c158ad (diff)
avfilter/curves: support slice threading.
Diffstat (limited to 'libavfilter/vf_curves.c')
-rw-r--r--libavfilter/vf_curves.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c
index 51234305fe..93799b0b1d 100644
--- a/libavfilter/vf_curves.c
+++ b/libavfilter/vf_curves.c
@@ -69,6 +69,10 @@ typedef struct {
int step;
} CurvesContext;
+typedef struct ThreadData {
+ AVFrame *in, *out;
+} ThreadData;
+
#define OFFSET(x) offsetof(CurvesContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
static const AVOption curves_options[] = {
@@ -473,23 +477,46 @@ static int config_input(AVFilterLink *inlink)
return 0;
}
-static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
- int x, y, direct = 0;
- AVFilterContext *ctx = inlink->dst;
- CurvesContext *curves = ctx->priv;
- AVFilterLink *outlink = ctx->outputs[0];
- AVFrame *out;
- uint8_t *dst;
- const uint8_t *src;
+ int x, y;
+ const CurvesContext *curves = ctx->priv;
+ const ThreadData *td = arg;
+ const AVFrame *in = td->in;
+ const AVFrame *out = td->out;
+ const int direct = out == in;
const int step = curves->step;
const uint8_t r = curves->rgba_map[R];
const uint8_t g = curves->rgba_map[G];
const uint8_t b = curves->rgba_map[B];
const uint8_t a = curves->rgba_map[A];
+ const int slice_start = (in->height * jobnr ) / nb_jobs;
+ const int slice_end = (in->height * (jobnr+1)) / nb_jobs;
+ uint8_t *dst = out->data[0] + slice_start * out->linesize[0];
+ const uint8_t *src = in->data[0] + slice_start * in->linesize[0];
+
+ for (y = slice_start; y < slice_end; y++) {
+ for (x = 0; x < in->width * step; x += step) {
+ dst[x + r] = curves->graph[R][src[x + r]];
+ dst[x + g] = curves->graph[G][src[x + g]];
+ dst[x + b] = curves->graph[B][src[x + b]];
+ if (!direct && step == 4)
+ dst[x + a] = src[x + a];
+ }
+ dst += out->linesize[0];
+ src += in ->linesize[0];
+ }
+ return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+ AVFilterContext *ctx = inlink->dst;
+ AVFilterLink *outlink = ctx->outputs[0];
+ AVFrame *out;
+ ThreadData td;
if (av_frame_is_writable(in)) {
- direct = 1;
out = in;
} else {
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
@@ -500,22 +527,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
av_frame_copy_props(out, in);
}
- dst = out->data[0];
- src = in ->data[0];
-
- for (y = 0; y < inlink->h; y++) {
- for (x = 0; x < inlink->w * step; x += step) {
- dst[x + r] = curves->graph[R][src[x + r]];
- dst[x + g] = curves->graph[G][src[x + g]];
- dst[x + b] = curves->graph[B][src[x + b]];
- if (!direct && step == 4)
- dst[x + a] = src[x + a];
- }
- dst += out->linesize[0];
- src += in ->linesize[0];
- }
+ td.in = in;
+ td.out = out;
+ ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outlink->h, ctx->graph->nb_threads));
- if (!direct)
+ if (out != in)
av_frame_free(&in);
return ff_filter_frame(outlink, out);
@@ -548,5 +564,5 @@ AVFilter ff_vf_curves = {
.inputs = curves_inputs,
.outputs = curves_outputs,
.priv_class = &curves_class,
- .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
+ .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
};