mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avfilter/curves: support slice threading.
This commit is contained in:
parent
842b6c14bc
commit
0e97ec54de
@ -69,6 +69,10 @@ typedef struct {
|
|||||||
int step;
|
int step;
|
||||||
} CurvesContext;
|
} CurvesContext;
|
||||||
|
|
||||||
|
typedef struct ThreadData {
|
||||||
|
AVFrame *in, *out;
|
||||||
|
} ThreadData;
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(CurvesContext, x)
|
#define OFFSET(x) offsetof(CurvesContext, x)
|
||||||
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
|
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
|
||||||
static const AVOption curves_options[] = {
|
static const AVOption curves_options[] = {
|
||||||
@ -473,23 +477,46 @@ static int config_input(AVFilterLink *inlink)
|
|||||||
return 0;
|
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;
|
int x, y;
|
||||||
AVFilterContext *ctx = inlink->dst;
|
const CurvesContext *curves = ctx->priv;
|
||||||
CurvesContext *curves = ctx->priv;
|
const ThreadData *td = arg;
|
||||||
AVFilterLink *outlink = ctx->outputs[0];
|
const AVFrame *in = td->in;
|
||||||
AVFrame *out;
|
const AVFrame *out = td->out;
|
||||||
uint8_t *dst;
|
const int direct = out == in;
|
||||||
const uint8_t *src;
|
|
||||||
const int step = curves->step;
|
const int step = curves->step;
|
||||||
const uint8_t r = curves->rgba_map[R];
|
const uint8_t r = curves->rgba_map[R];
|
||||||
const uint8_t g = curves->rgba_map[G];
|
const uint8_t g = curves->rgba_map[G];
|
||||||
const uint8_t b = curves->rgba_map[B];
|
const uint8_t b = curves->rgba_map[B];
|
||||||
const uint8_t a = curves->rgba_map[A];
|
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)) {
|
if (av_frame_is_writable(in)) {
|
||||||
direct = 1;
|
|
||||||
out = in;
|
out = in;
|
||||||
} else {
|
} else {
|
||||||
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
|
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);
|
av_frame_copy_props(out, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
dst = out->data[0];
|
td.in = in;
|
||||||
src = in ->data[0];
|
td.out = out;
|
||||||
|
ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outlink->h, ctx->graph->nb_threads));
|
||||||
|
|
||||||
for (y = 0; y < inlink->h; y++) {
|
if (out != in)
|
||||||
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];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!direct)
|
|
||||||
av_frame_free(&in);
|
av_frame_free(&in);
|
||||||
|
|
||||||
return ff_filter_frame(outlink, out);
|
return ff_filter_frame(outlink, out);
|
||||||
@ -548,5 +564,5 @@ AVFilter ff_vf_curves = {
|
|||||||
.inputs = curves_inputs,
|
.inputs = curves_inputs,
|
||||||
.outputs = curves_outputs,
|
.outputs = curves_outputs,
|
||||||
.priv_class = &curves_class,
|
.priv_class = &curves_class,
|
||||||
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
|
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user