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:
authorPaul B Mahol <onemda@gmail.com>2018-05-12 16:46:28 +0300
committerPaul B Mahol <onemda@gmail.com>2018-05-12 16:46:28 +0300
commit1c2e5fc4546f2c80212add77015003de200f7963 (patch)
tree86f14810cfe92a5c73a07390877152dcfc09ce1f /libavfilter/vf_maskedmerge.c
parent9b6f8fb25df6143eb167db6291a156a34f91b23d (diff)
avfilter/vf_maskedmerge: add slice threading
Signed-off-by: Paul B Mahol <onemda@gmail.com>
Diffstat (limited to 'libavfilter/vf_maskedmerge.c')
-rw-r--r--libavfilter/vf_maskedmerge.c67
1 files changed, 50 insertions, 17 deletions
diff --git a/libavfilter/vf_maskedmerge.c b/libavfilter/vf_maskedmerge.c
index 86559abdac..ab9da7e901 100644
--- a/libavfilter/vf_maskedmerge.c
+++ b/libavfilter/vf_maskedmerge.c
@@ -63,12 +63,55 @@ static int query_formats(AVFilterContext *ctx)
return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
}
+typedef struct ThreadData {
+ AVFrame *base, *overlay, *mask;
+ AVFrame *out;
+} ThreadData;
+
+static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+ MaskedMergeContext *s = ctx->priv;
+ ThreadData *td = arg;
+ AVFrame *base = td->base;
+ AVFrame *overlay = td->overlay;
+ AVFrame *mask = td->mask;
+ AVFrame *out = td->out;
+ int p;
+
+ for (p = 0; p < s->nb_planes; p++) {
+ const int h = s->height[p];
+ const int slice_start = (h * jobnr) / nb_jobs;
+ const int slice_end = (h * (jobnr+1)) / nb_jobs;
+
+ if (!((1 << p) & s->planes)) {
+ av_image_copy_plane(out->data[p] + slice_start * out->linesize[p],
+ out->linesize[p],
+ base->data[p] + slice_start * base->linesize[p],
+ base->linesize[p],
+ s->linesize[p], slice_end - slice_start);
+ continue;
+ }
+
+ s->maskedmerge(base->data[p] + slice_start * base->linesize[p],
+ overlay->data[p] + slice_start * overlay->linesize[p],
+ mask->data[p] + slice_start * mask->linesize[p],
+ out->data[p] + slice_start * out->linesize[p],
+ base->linesize[p], overlay->linesize[p],
+ mask->linesize[p], out->linesize[p],
+ s->width[p], slice_end - slice_start,
+ s->half, s->depth);
+ }
+
+ return 0;
+}
+
static int process_frame(FFFrameSync *fs)
{
AVFilterContext *ctx = fs->parent;
MaskedMergeContext *s = fs->opaque;
AVFilterLink *outlink = ctx->outputs[0];
AVFrame *out, *base, *overlay, *mask;
+ ThreadData td;
int ret;
if ((ret = ff_framesync_get_frame(&s->fs, 0, &base, 0)) < 0 ||
@@ -81,27 +124,17 @@ static int process_frame(FFFrameSync *fs)
if (!out)
return AVERROR(ENOMEM);
} else {
- int p;
-
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out)
return AVERROR(ENOMEM);
av_frame_copy_props(out, base);
- for (p = 0; p < s->nb_planes; p++) {
- if (!((1 << p) & s->planes)) {
- av_image_copy_plane(out->data[p], out->linesize[p], base->data[p], base->linesize[p],
- s->linesize[p], s->height[p]);
- continue;
- }
-
- s->maskedmerge(base->data[p], overlay->data[p],
- mask->data[p], out->data[p],
- base->linesize[p], overlay->linesize[p],
- mask->linesize[p], out->linesize[p],
- s->width[p], s->height[p],
- s->half, s->depth);
- }
+ td.out = out;
+ td.base = base;
+ td.overlay = overlay;
+ td.mask = mask;
+ ctx->internal->execute(ctx, filter_slice, &td, NULL,
+ FFMIN(s->height[2], ff_filter_get_nb_threads(ctx)));
}
out->pts = av_rescale_q(base->pts, s->fs.time_base, outlink->time_base);
@@ -291,5 +324,5 @@ AVFilter ff_vf_maskedmerge = {
.inputs = maskedmerge_inputs,
.outputs = maskedmerge_outputs,
.priv_class = &maskedmerge_class,
- .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
+ .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
};