This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit ba1c1d9eee75a2bd5f2677907af1753112c5c69f Author: Niklas Haas <[email protected]> AuthorDate: Sat Jun 20 02:55:31 2026 +0200 Commit: Niklas Haas <[email protected]> CommitDate: Sat Jun 20 03:04:27 2026 +0200 swscale/graph: separate pass dispatch size from buffer size This allows adding passes which will be dispatched over a reduced number of lines, without affecting the allocated buffer dimensions - e.g. for passes which purely write to subsampled chroma planes. A few hard-coded references to pass->width/height need to be replaced by the corresponding output frame references, but it's not a huge deal. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas <[email protected]> --- libswscale/graph.c | 43 +++++++++++++++++++++++-------------------- libswscale/graph.h | 6 ++++-- libswscale/ops_dispatch.c | 15 ++++++++------- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/libswscale/graph.c b/libswscale/graph.c index 06e5ebefc8..a765b4cd5c 100644 --- a/libswscale/graph.c +++ b/libswscale/graph.c @@ -174,7 +174,8 @@ static void pass_free(SwsPass *pass) int ff_sws_graph_add_pass(SwsGraph *graph, enum AVPixelFormat fmt, int width, int height, SwsPass *input, - int align, SwsPassFunc run, SwsPassSetup setup, + int lines, int align, + SwsPassFunc run, SwsPassSetup setup, void *priv, void (*free_cb)(void *priv), SwsPass **out_pass) { @@ -186,14 +187,16 @@ int ff_sws_graph_add_pass(SwsGraph *graph, enum AVPixelFormat fmt, return AVERROR(ENOMEM); } + if (!lines) + lines = height; + pass->graph = graph; pass->run = run; pass->setup = setup; pass->priv = priv; pass->free = free_cb; pass->format = fmt; - pass->width = width; - pass->height = height; + pass->lines = lines; pass->input = input; pass->output = av_refstruct_alloc_ext(sizeof(*pass->output), 0, NULL, free_buffer); if (!pass->output) { @@ -201,17 +204,17 @@ int ff_sws_graph_add_pass(SwsGraph *graph, enum AVPixelFormat fmt, goto fail; } - pass->output->height = pass->height; - pass->output->width = pass->width; + pass->output->height = height; + pass->output->width = width; pass->output->width_align = 1; if (!align) { - pass->slice_h = pass->height; + pass->slice_h = pass->lines; pass->num_slices = 1; } else { - pass->slice_h = (pass->height + graph->num_threads - 1) / graph->num_threads; + pass->slice_h = (pass->lines + graph->num_threads - 1) / graph->num_threads; pass->slice_h = FFALIGN(pass->slice_h, align); - pass->num_slices = (pass->height + pass->slice_h - 1) / pass->slice_h; + pass->num_slices = (pass->lines + pass->slice_h - 1) / pass->slice_h; } ret = av_dynarray_add_nofree(&graph->passes, &graph->num_passes, pass); @@ -267,7 +270,7 @@ static void run_rgb0(const SwsFrame *out, const SwsFrame *in, int y, int h, { SwsInternal *c = pass->priv; const int x0 = c->src0Alpha - 1; - const int w4 = 4 * pass->width; + const int w4 = 4 * out->width; const int src_stride = in->linesize[0]; const int dst_stride = out->linesize[0]; const uint8_t *src = in->data[0] + y * src_stride; @@ -289,7 +292,7 @@ static void run_xyz2rgb(const SwsFrame *out, const SwsFrame *in, int y, int h, const SwsInternal *c = pass->priv; c->xyz12Torgb48(c, out->data[0] + y * out->linesize[0], out->linesize[0], in->data[0] + y * in->linesize[0], in->linesize[0], - pass->width, h); + out->width, h); } static void run_rgb2xyz(const SwsFrame *out, const SwsFrame *in, int y, int h, @@ -298,7 +301,7 @@ static void run_rgb2xyz(const SwsFrame *out, const SwsFrame *in, int y, int h, const SwsInternal *c = pass->priv; c->rgb48Toxyz12(c, out->data[0] + y * out->linesize[0], out->linesize[0], in->data[0] + y * in->linesize[0], in->linesize[0], - pass->width, h); + out->width, h); } /*********************************************************************** @@ -465,7 +468,7 @@ static int init_legacy_subpass(SwsGraph *graph, SwsContext *sws, if (c->src0Alpha && !c->dst0Alpha && isALPHA(sws->dst_format)) { ret = ff_sws_graph_add_pass(graph, AV_PIX_FMT_RGBA, src_w, src_h, input, - 1, run_rgb0, NULL, c, NULL, &input); + 0, 1, run_rgb0, NULL, c, NULL, &input); if (ret < 0) { sws_free_context(&sws); return ret; @@ -474,14 +477,14 @@ static int init_legacy_subpass(SwsGraph *graph, SwsContext *sws, if (c->srcXYZ && !(c->dstXYZ && unscaled)) { ret = ff_sws_graph_add_pass(graph, AV_PIX_FMT_RGB48, src_w, src_h, input, - 1, run_xyz2rgb, NULL, c, NULL, &input); + 0, 1, run_xyz2rgb, NULL, c, NULL, &input); if (ret < 0) { sws_free_context(&sws); return ret; } } - ret = ff_sws_graph_add_pass(graph, sws->dst_format, dst_w, dst_h, input, align, + ret = ff_sws_graph_add_pass(graph, sws->dst_format, dst_w, dst_h, input, 0, align, c->convert_unscaled ? run_legacy_unscaled : run_legacy_swscale, setup_legacy_swscale, sws, free_legacy_swscale, &pass); if (ret < 0) @@ -533,7 +536,7 @@ static int init_legacy_subpass(SwsGraph *graph, SwsContext *sws, if (c->dstXYZ && !(c->srcXYZ && unscaled)) { ret = ff_sws_graph_add_pass(graph, AV_PIX_FMT_RGB48, dst_w, dst_h, pass, - 1, run_rgb2xyz, NULL, c, NULL, &pass); + 0, 1, run_rgb2xyz, NULL, c, NULL, &pass); if (ret < 0) return ret; } @@ -715,7 +718,7 @@ static void run_lut3d(const SwsFrame *out, const SwsFrame *in, int y, int h, frame_shift(out, y, out_data); ff_sws_lut3d_apply(lut, in_data[0], in->linesize[0], out_data[0], - out->linesize[0], pass->width, h); + out->linesize[0], out->width, h); } static int adapt_colors(SwsGraph *graph, const SwsFormat *src_fmt, @@ -777,7 +780,7 @@ static int adapt_colors(SwsGraph *graph, const SwsFormat *src_fmt, } return ff_sws_graph_add_pass(graph, fmt_out, src.width, src.height, - input, 1, run_lut3d, setup_lut3d, lut, + input, 0, 1, run_lut3d, setup_lut3d, lut, free_lut3d, output); } @@ -812,7 +815,7 @@ static int init_passes(SwsGraph *graph) /* Add threaded memcpy pass */ return ff_sws_graph_add_pass(graph, dst.format, dst.width, dst.height, - pass, 1, run_copy, NULL, NULL, NULL, &pass); + pass, 0, 1, run_copy, NULL, NULL, NULL, &pass); } static void sws_graph_worker(void *priv, int jobnr, int threadnr, int nb_jobs, @@ -821,7 +824,7 @@ static void sws_graph_worker(void *priv, int jobnr, int threadnr, int nb_jobs, SwsGraph *graph = priv; const SwsPass *pass = graph->exec.pass; const int slice_y = jobnr * pass->slice_h; - const int slice_h = FFMIN(pass->slice_h, pass->height - slice_y); + const int slice_h = FFMIN(pass->slice_h, pass->lines - slice_y); pass->run(graph->exec.output, graph->exec.input, slice_y, slice_h, pass); } @@ -1016,7 +1019,7 @@ int ff_sws_graph_run(SwsGraph *graph, const AVFrame *dst, const AVFrame *src) } if (pass->num_slices == 1) { - pass->run(graph->exec.output, graph->exec.input, 0, pass->height, pass); + pass->run(graph->exec.output, graph->exec.input, 0, pass->lines, pass); } else { avpriv_slicethread_execute(graph->slicethread, pass->num_slices, 0); } diff --git a/libswscale/graph.h b/libswscale/graph.h index adf4b19675..eff2dcc47f 100644 --- a/libswscale/graph.h +++ b/libswscale/graph.h @@ -83,7 +83,7 @@ struct SwsPass { SwsPassFunc run; SwsBackend backend; /* backend this pass is using, or 0 */ enum AVPixelFormat format; /* new pixel format */ - int width, height; /* new output size */ + int lines; /* pass dispatch size */ int slice_h; /* filter granularity */ int num_slices; @@ -184,6 +184,7 @@ int ff_sws_graph_create(SwsContext *ctx, const SwsFormat *dst, const SwsFormat * * @param w Width of the output image. * @param h Height of the output image. * @param input Previous pass to read from, or NULL for the input image. + * @param lines Override the number of lines processed for this pass. (Optional) * @param align Minimum slice alignment for this pass, or 0 for no threading. * @param run Filter function to run. * @param setup Optional setup function to run from the main thread. @@ -194,7 +195,8 @@ int ff_sws_graph_create(SwsContext *ctx, const SwsFormat *dst, const SwsFormat * */ int ff_sws_graph_add_pass(SwsGraph *graph, enum AVPixelFormat fmt, int width, int height, SwsPass *input, - int align, SwsPassFunc run, SwsPassSetup setup, + int lines, int align, + SwsPassFunc run, SwsPassSetup setup, void *priv, void (*free)(void *priv), SwsPass **out_pass); diff --git a/libswscale/ops_dispatch.c b/libswscale/ops_dispatch.c index 44248195d7..abf67b0d55 100644 --- a/libswscale/ops_dispatch.c +++ b/libswscale/ops_dispatch.c @@ -202,6 +202,7 @@ static int op_pass_setup(const SwsFrame *out, const SwsFrame *in, { const AVPixFmtDescriptor *indesc = av_pix_fmt_desc_get(in->format); const bool float_in = indesc->flags & AV_PIX_FMT_FLAG_FLOAT; + const int width = out->width; SwsOpPass *p = pass->priv; SwsOpExec *exec = &p->exec_base; @@ -209,9 +210,9 @@ static int op_pass_setup(const SwsFrame *out, const SwsFrame *in, /* Set up main loop parameters */ const unsigned block_size = comp->block_size; - const size_t num_blocks = (pass->width + block_size - 1) / block_size; + const size_t num_blocks = (width + block_size - 1) / block_size; const size_t aligned_w = num_blocks * block_size; - if (aligned_w < pass->width) /* overflow */ + if (aligned_w < width) /* overflow */ return AVERROR(EINVAL); p->num_blocks = num_blocks; p->memcpy_first = false; @@ -280,14 +281,14 @@ static int op_pass_setup(const SwsFrame *out, const SwsFrame *in, *tail = *exec; const size_t safe_width = safe_blocks * block_size; - const size_t tail_size = pass->width - safe_width; + const size_t tail_size = width - safe_width; p->tail_off_out = pixel_bytes(safe_width, p->pixel_bits_out, AV_ROUND_DOWN); p->tail_size_out = pixel_bytes(tail_size, p->pixel_bits_out, AV_ROUND_UP); p->tail_blocks = num_blocks - safe_blocks; if (exec->in_offset_x) { p->tail_off_in = exec->in_offset_x[safe_width]; - p->tail_size_in = exec->in_offset_x[pass->width - 1] - p->tail_off_in; + p->tail_size_in = exec->in_offset_x[width - 1] - p->tail_off_in; p->tail_size_in += pixel_bytes(p->filter_size_h, p->pixel_bits_in, AV_ROUND_UP); } else { p->tail_off_in = pixel_bytes(safe_width, p->pixel_bits_in, AV_ROUND_DOWN); @@ -387,7 +388,7 @@ static void op_pass_run(const SwsFrame *out, const SwsFrame *in, const int y, * memcpy the last column on the output side if unpadded. */ - const bool memcpy_in = p->memcpy_last && y + h == pass->height || + const bool memcpy_in = p->memcpy_last && y + h == pass->lines || p->memcpy_first && y == 0; const bool memcpy_out = p->memcpy_out; const size_t num_blocks = p->num_blocks; @@ -515,7 +516,7 @@ static int compile(SwsGraph *graph, const SwsOpBackend *backend, SwsCompiledOp c = *comp; av_free(p); ret = ff_sws_graph_add_pass(graph, dst->format, dst->width, dst->height, - input, c.slice_align, c.func_opaque, + input, 0, c.slice_align, c.func_opaque, NULL, c.priv, c.free, output); if (ret >= 0) (*output)->backend = comp->backend->flags; @@ -616,7 +617,7 @@ static int compile(SwsGraph *graph, const SwsOpBackend *backend, } ret = ff_sws_graph_add_pass(graph, dst->format, dst->width, dst->height, - input, comp->slice_align, op_pass_run, + input, 0, comp->slice_align, op_pass_run, op_pass_setup, p, op_pass_free, output); if (ret < 0) return ret; _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
