From d6fdc78e9164c8e6bf7bfc7766932c467b874aa2 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 12 Jul 2021 12:31:14 +0200 Subject: sws: implement slice threading --- libswscale/swscale.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'libswscale/swscale.c') diff --git a/libswscale/swscale.c b/libswscale/swscale.c index ca5c612b18..c233818dcf 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -1113,6 +1113,9 @@ int sws_send_slice(struct SwsContext *c, unsigned int slice_start, unsigned int sws_receive_slice_alignment(const struct SwsContext *c) { + if (c->slice_ctx) + return c->slice_ctx[0]->dst_slice_align; + return c->dst_slice_align; } @@ -1136,6 +1139,27 @@ int sws_receive_slice(struct SwsContext *c, unsigned int slice_start, return AVERROR(EINVAL); } + if (c->slicethread) { + int nb_jobs = c->slice_ctx[0]->dither == SWS_DITHER_ED ? 1 : c->nb_slice_ctx; + int ret = 0; + + c->dst_slice_start = slice_start; + c->dst_slice_height = slice_height; + + avpriv_slicethread_execute(c->slicethread, nb_jobs, 0); + + for (int i = 0; i < c->nb_slice_ctx; i++) { + if (c->slice_err[i] < 0) { + ret = c->slice_err[i]; + break; + } + } + + memset(c->slice_err, 0, c->nb_slice_ctx * sizeof(*c->slice_err)); + + return ret; + } + for (int i = 0; i < FF_ARRAY_ELEMS(dst) && c->frame_dst->data[i]; i++) { dst[i] = c->frame_dst->data[i] + c->frame_dst->linesize[i] * (slice_start >> c->chrDstVSubSample); @@ -1173,6 +1197,41 @@ int attribute_align_arg sws_scale(struct SwsContext *c, int srcSliceH, uint8_t *const dst[], const int dstStride[]) { + if (c->nb_slice_ctx) + c = c->slice_ctx[0]; + return scale_internal(c, srcSlice, srcStride, srcSliceY, srcSliceH, dst, dstStride, 0, c->dstH); } + +void ff_sws_slice_worker(void *priv, int jobnr, int threadnr, + int nb_jobs, int nb_threads) +{ + SwsContext *parent = priv; + SwsContext *c = parent->slice_ctx[threadnr]; + + const int slice_height = FFALIGN(FFMAX((parent->dst_slice_height + nb_jobs - 1) / nb_jobs, 1), + c->dst_slice_align); + const int slice_start = jobnr * slice_height; + const int slice_end = FFMIN((jobnr + 1) * slice_height, parent->dst_slice_height); + int err = 0; + + if (slice_end > slice_start) { + uint8_t *dst[4] = { NULL }; + + for (int i = 0; i < FF_ARRAY_ELEMS(dst) && parent->frame_dst->data[i]; i++) { + const int vshift = (i == 1 || i == 2) ? c->chrDstVSubSample : 0; + const ptrdiff_t offset = parent->frame_dst->linesize[i] * + ((slice_start + parent->dst_slice_start) >> vshift); + + dst[i] = parent->frame_dst->data[i] + offset; + } + + err = scale_internal(c, (const uint8_t * const *)parent->frame_src->data, + parent->frame_src->linesize, 0, c->srcH, + dst, parent->frame_dst->linesize, + parent->dst_slice_start + slice_start, slice_end - slice_start); + } + + parent->slice_err[threadnr] = err; +} -- cgit v1.2.3