avfilter/vf_premultiply: add slice threading
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
		
							parent
							
								
									e0e75f93b9
								
							
						
					
					
						commit
						2d7ba3a96f
					
				@ -28,6 +28,10 @@
 | 
			
		||||
#include "internal.h"
 | 
			
		||||
#include "video.h"
 | 
			
		||||
 | 
			
		||||
typedef struct ThreadData {
 | 
			
		||||
    AVFrame *m, *a, *d;
 | 
			
		||||
} ThreadData;
 | 
			
		||||
 | 
			
		||||
typedef struct PreMultiplyContext {
 | 
			
		||||
    const AVClass *class;
 | 
			
		||||
    int width[4], height[4];
 | 
			
		||||
@ -361,6 +365,41 @@ static void unpremultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int premultiply_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
 | 
			
		||||
{
 | 
			
		||||
    PreMultiplyContext *s = ctx->priv;
 | 
			
		||||
    ThreadData *td = arg;
 | 
			
		||||
    AVFrame *out = td->d;
 | 
			
		||||
    AVFrame *alpha = td->a;
 | 
			
		||||
    AVFrame *base = td->m;
 | 
			
		||||
    int p;
 | 
			
		||||
 | 
			
		||||
    for (p = 0; p < s->nb_planes; p++) {
 | 
			
		||||
        const int slice_start = (s->height[p] * jobnr) / nb_jobs;
 | 
			
		||||
        const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;
 | 
			
		||||
 | 
			
		||||
        if (!((1 << p) & s->planes) || p == 3) {
 | 
			
		||||
            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->premultiply[p](base->data[p] + slice_start * base->linesize[p],
 | 
			
		||||
                          s->inplace ? alpha->data[3] + slice_start * alpha->linesize[3] :
 | 
			
		||||
                                       alpha->data[0] + slice_start * alpha->linesize[0],
 | 
			
		||||
                          out->data[p] + slice_start * out->linesize[p],
 | 
			
		||||
                          base->linesize[p], s->inplace ? alpha->linesize[3] : alpha->linesize[0],
 | 
			
		||||
                          out->linesize[p],
 | 
			
		||||
                          s->width[p], slice_end - slice_start,
 | 
			
		||||
                          s->half, s->inverse ? s->max : s->depth, s->offset);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int filter_frame(AVFilterContext *ctx,
 | 
			
		||||
                        AVFrame **out, AVFrame *base, AVFrame *alpha)
 | 
			
		||||
{
 | 
			
		||||
@ -372,7 +411,8 @@ static int filter_frame(AVFilterContext *ctx,
 | 
			
		||||
        if (!*out)
 | 
			
		||||
            return AVERROR(ENOMEM);
 | 
			
		||||
    } else {
 | 
			
		||||
        int p, full, limited;
 | 
			
		||||
        ThreadData td;
 | 
			
		||||
        int full, limited;
 | 
			
		||||
 | 
			
		||||
        *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
 | 
			
		||||
        if (!*out)
 | 
			
		||||
@ -476,20 +516,11 @@ static int filter_frame(AVFilterContext *ctx,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (p = 0; p < s->nb_planes; p++) {
 | 
			
		||||
            if (!((1 << p) & s->planes) || p == 3) {
 | 
			
		||||
                av_image_copy_plane((*out)->data[p], (*out)->linesize[p], base->data[p], base->linesize[p],
 | 
			
		||||
                                    s->linesize[p], s->height[p]);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            s->premultiply[p](base->data[p], s->inplace ? alpha->data[3] : alpha->data[0],
 | 
			
		||||
                              (*out)->data[p],
 | 
			
		||||
                              base->linesize[p], s->inplace ? alpha->linesize[3] : alpha->linesize[0],
 | 
			
		||||
                              (*out)->linesize[p],
 | 
			
		||||
                              s->width[p], s->height[p],
 | 
			
		||||
                              s->half, s->inverse ? s->max : s->depth, s->offset);
 | 
			
		||||
        }
 | 
			
		||||
        td.d = *out;
 | 
			
		||||
        td.a = alpha;
 | 
			
		||||
        td.m = base;
 | 
			
		||||
        ctx->internal->execute(ctx, premultiply_slice, &td, NULL, FFMIN(s->height[0],
 | 
			
		||||
                                                                        ff_filter_get_nb_threads(ctx)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
@ -695,7 +726,8 @@ AVFilter ff_vf_premultiply = {
 | 
			
		||||
    .outputs       = premultiply_outputs,
 | 
			
		||||
    .priv_class    = &premultiply_class,
 | 
			
		||||
    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
 | 
			
		||||
                     AVFILTER_FLAG_DYNAMIC_INPUTS,
 | 
			
		||||
                     AVFILTER_FLAG_DYNAMIC_INPUTS |
 | 
			
		||||
                     AVFILTER_FLAG_SLICE_THREADS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* CONFIG_PREMULTIPLY_FILTER */
 | 
			
		||||
@ -717,7 +749,8 @@ AVFilter ff_vf_unpremultiply = {
 | 
			
		||||
    .outputs       = premultiply_outputs,
 | 
			
		||||
    .priv_class    = &unpremultiply_class,
 | 
			
		||||
    .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
 | 
			
		||||
                     AVFILTER_FLAG_DYNAMIC_INPUTS,
 | 
			
		||||
                     AVFILTER_FLAG_DYNAMIC_INPUTS |
 | 
			
		||||
                     AVFILTER_FLAG_SLICE_THREADS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* CONFIG_UNPREMULTIPLY_FILTER */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user