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:
authorAnton Khirnov <anton@khirnov.net>2021-07-12 13:31:14 +0300
committerAnton Khirnov <anton@khirnov.net>2021-09-06 10:17:53 +0300
commitd6fdc78e9164c8e6bf7bfc7766932c467b874aa2 (patch)
treedd3ba9ef975f1838ede89d9c693f86d079878600 /libswscale/swscale.c
parent22c6fbc8475f99b67ded526ace496cdd5362074b (diff)
sws: implement slice threading
Diffstat (limited to 'libswscale/swscale.c')
-rw-r--r--libswscale/swscale.c59
1 files changed, 59 insertions, 0 deletions
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;
+}