PR #22520 opened by Ramiro Polla (ramiro) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22520 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22520.patch
Also fixes a typo and a cosmetic assignment to itself. NOTE: still missing fixing `adapt_colors()` from `libswscale/graph.c`. >From 33199331bd3db84e3e6ca2858a480fbd59f1910a Mon Sep 17 00:00:00 2001 From: Ramiro Polla <[email protected]> Date: Mon, 16 Mar 2026 16:33:42 +0100 Subject: [PATCH 1/4] swscale/graph: fix typo in graph.h --- libswscale/graph.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/graph.h b/libswscale/graph.h index 4267851baa..5a16f05538 100644 --- a/libswscale/graph.h +++ b/libswscale/graph.h @@ -81,7 +81,7 @@ struct SwsPass { int num_slices; /** - * Filter input. This pass's output will be resolved to form this pass's. + * Filter input. This pass's output will be resolved to form this pass's * input. If NULL, the original input image is used. */ const SwsPass *input; -- 2.52.0 >From 8458671f8d9f1566e712511e52b9e1b97d4c610e Mon Sep 17 00:00:00 2001 From: Ramiro Polla <[email protected]> Date: Mon, 16 Mar 2026 16:45:35 +0100 Subject: [PATCH 2/4] swscale/graph: avoid assigning a variable to itself --- libswscale/graph.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libswscale/graph.c b/libswscale/graph.c index db11591862..6efd149297 100644 --- a/libswscale/graph.c +++ b/libswscale/graph.c @@ -731,7 +731,8 @@ static int init_passes(SwsGraph *graph) ret = adapt_colors(graph, src, dst, pass, &pass); if (ret < 0) return ret; - src.format = pass ? pass->format : src.format; + if (pass) + src.format = pass->format; src.color = dst.color; if (!ff_fmt_equal(&src, &dst)) { -- 2.52.0 >From 261dd51b37ac487f8f94447efa3e7ae24ac422a5 Mon Sep 17 00:00:00 2001 From: Ramiro Polla <[email protected]> Date: Mon, 16 Mar 2026 16:16:39 +0100 Subject: [PATCH 3/4] swscale: pass SwsColor/SwsFormat/SwsPass arguments by pointer, not by value For exported functions, passing structs by value requires copying them onto the stack, while pointers don't requires such copies. For static functions, the compiler would likely optimize both forms to the same result, but for consistency and to avoid confusion, always use pointers to structs as function arguments. --- libswscale/format.c | 6 +++--- libswscale/graph.c | 4 ++-- libswscale/lut3d.c | 2 +- libswscale/lut3d.h | 2 +- libswscale/ops.c | 14 +++++++------- libswscale/ops.h | 2 +- libswscale/ops_chain.c | 10 +++++----- libswscale/ops_optimizer.c | 24 +++++++++++++----------- 8 files changed, 33 insertions(+), 31 deletions(-) diff --git a/libswscale/format.c b/libswscale/format.c index 3464a8af7c..b82d5a65dd 100644 --- a/libswscale/format.c +++ b/libswscale/format.c @@ -1150,7 +1150,7 @@ static SwsLinearOp fmt_encode_range(const SwsFormat *fmt, bool *incomplete) c.m[0][0] = av_neg_q(c.m[0][0]); } - c.mask = ff_sws_linear_mask(c); + c.mask = ff_sws_linear_mask(&c); return c; } @@ -1169,7 +1169,7 @@ static SwsLinearOp fmt_decode_range(const SwsFormat *fmt, bool *incomplete) if (!(fmt->desc->flags & AV_PIX_FMT_FLAG_ALPHA)) c.m[3][4] = Q1; - c.mask = ff_sws_linear_mask(c); + c.mask = ff_sws_linear_mask(&c); return c; } @@ -1324,7 +1324,7 @@ linear_mat3(const AVRational m00, const AVRational m01, const AVRational m02, { Q0, Q0, Q0, Q1, Q0 }, }}; - c.mask = ff_sws_linear_mask(c); + c.mask = ff_sws_linear_mask(&c); return c; } diff --git a/libswscale/graph.c b/libswscale/graph.c index 6efd149297..2af775d990 100644 --- a/libswscale/graph.c +++ b/libswscale/graph.c @@ -696,8 +696,8 @@ static int adapt_colors(SwsGraph *graph, SwsFormat src, SwsFormat dst, if (!lut) return AVERROR(ENOMEM); - fmt_in = ff_sws_lut3d_pick_pixfmt(src, 0); - fmt_out = ff_sws_lut3d_pick_pixfmt(dst, 1); + fmt_in = ff_sws_lut3d_pick_pixfmt(&src, 0); + fmt_out = ff_sws_lut3d_pick_pixfmt(&dst, 1); if (fmt_in != src.format) { SwsFormat tmp = src; tmp.format = fmt_in; diff --git a/libswscale/lut3d.c b/libswscale/lut3d.c index 535694e61c..d701ca2ba5 100644 --- a/libswscale/lut3d.c +++ b/libswscale/lut3d.c @@ -49,7 +49,7 @@ bool ff_sws_lut3d_test_fmt(enum AVPixelFormat fmt, int output) return fmt == AV_PIX_FMT_RGBA64; } -enum AVPixelFormat ff_sws_lut3d_pick_pixfmt(SwsFormat fmt, int output) +enum AVPixelFormat ff_sws_lut3d_pick_pixfmt(const SwsFormat *fmt, int output) { return AV_PIX_FMT_RGBA64; } diff --git a/libswscale/lut3d.h b/libswscale/lut3d.h index 273059f9a1..d2de851604 100644 --- a/libswscale/lut3d.h +++ b/libswscale/lut3d.h @@ -70,7 +70,7 @@ bool ff_sws_lut3d_test_fmt(enum AVPixelFormat fmt, int output); /** * Pick the best compatible pixfmt for a given SwsFormat. */ -enum AVPixelFormat ff_sws_lut3d_pick_pixfmt(SwsFormat fmt, int output); +enum AVPixelFormat ff_sws_lut3d_pick_pixfmt(const SwsFormat *fmt, int output); /** * Recalculate the (static) 3DLUT state with new settings. This will recompute diff --git a/libswscale/ops.c b/libswscale/ops.c index 9bea2f0b4f..393986540a 100644 --- a/libswscale/ops.c +++ b/libswscale/ops.c @@ -654,12 +654,12 @@ int ff_sws_op_list_max_size(const SwsOpList *ops) return max_size; } -uint32_t ff_sws_linear_mask(const SwsLinearOp c) +uint32_t ff_sws_linear_mask(const SwsLinearOp *c) { uint32_t mask = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 5; j++) { - if (av_cmp_q(c.m[i][j], Q(i == j))) + if (av_cmp_q(c->m[i][j], Q(i == j))) mask |= SWS_MASK(i, j); } } @@ -721,14 +721,14 @@ static char describe_comp_flags(SwsCompFlags flags) return '.'; } -static const char *describe_order(SwsSwizzleOp order, int planes, char buf[32]) +static const char *describe_order(const SwsSwizzleOp *order, int planes, char buf[32]) { - if (order.mask == SWS_SWIZZLE(0, 1, 2, 3).mask) + if (order->mask == SWS_SWIZZLE(0, 1, 2, 3).mask) return ""; av_strlcpy(buf, ", via {", 32); for (int i = 0; i < planes; i++) - av_strlcatf(buf, 32, "%s%d", i ? ", " : "", order.in[i]); + av_strlcatf(buf, 32, "%s%d", i ? ", " : "", order->in[i]); av_strlcat(buf, "}", 32); return buf; } @@ -786,8 +786,8 @@ void ff_sws_op_list_print(void *log, int lev, int lev_extra, av_log(log, lev, "%-20s: %d elem(s) %s >> %d%s\n", name, op->rw.elems, op->rw.packed ? "packed" : "planar", op->rw.frac, - describe_order(op->op == SWS_OP_READ ? ops->order_src - : ops->order_dst, + describe_order(op->op == SWS_OP_READ ? &ops->order_src + : &ops->order_dst, op->rw.packed ? 1 : op->rw.elems, buf)); break; case SWS_OP_LSHIFT: diff --git a/libswscale/ops.h b/libswscale/ops.h index bc8e751f7b..21a57c70ee 100644 --- a/libswscale/ops.h +++ b/libswscale/ops.h @@ -183,7 +183,7 @@ enum { }; /* Helper function to compute the correct mask */ -uint32_t ff_sws_linear_mask(SwsLinearOp); +uint32_t ff_sws_linear_mask(const SwsLinearOp *c); typedef struct SwsOp { SwsOpType op; /* operation to perform */ diff --git a/libswscale/ops_chain.c b/libswscale/ops_chain.c index 1a4ac539ba..a2c8b7124b 100644 --- a/libswscale/ops_chain.c +++ b/libswscale/ops_chain.c @@ -79,7 +79,7 @@ int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr func, * is true, the op body is ignored - only the operation, pixel type, and * component masks are checked. */ -static int op_match(const SwsOp *op, const SwsOpEntry *entry, const SwsComps next) +static int op_match(const SwsOp *op, const SwsOpEntry *entry, const SwsComps *next) { int score = 10; if (op->op != entry->op) @@ -112,7 +112,7 @@ static int op_match(const SwsOp *op, const SwsOpEntry *entry, const SwsComps nex if (op->op == SWS_OP_CLEAR) { /* Clear pattern must match exactly, regardless of `entry->flexible` */ for (int i = 0; i < 4; i++) { - if (!next.unused[i] && entry->unused[i] != !!op->c.q4[i].den) + if (!next->unused[i] && entry->unused[i] != !!op->c.q4[i].den) return 0; } } @@ -145,7 +145,7 @@ static int op_match(const SwsOp *op, const SwsOpEntry *entry, const SwsComps nex for (int i = 0; i < 4; i++) { if (!op->c.q4[i].den) continue; - if (av_cmp_q(op->c.q4[i], Q(entry->clear_value)) && !next.unused[i]) + if (av_cmp_q(op->c.q4[i], Q(entry->clear_value)) && !next->unused[i]) return 0; } return score; @@ -155,7 +155,7 @@ static int op_match(const SwsOp *op, const SwsOpEntry *entry, const SwsComps nex break; case SWS_OP_SWIZZLE: for (int i = 0; i < 4; i++) { - if (op->swizzle.in[i] != entry->swizzle.in[i] && !next.unused[i]) + if (op->swizzle.in[i] != entry->swizzle.in[i] && !next->unused[i]) return 0; } return score; @@ -213,7 +213,7 @@ int ff_sws_op_compile_tables(const SwsOpTable *const tables[], int num_tables, for (int i = 0; table->entries[i]; i++) { const SwsOpEntry *entry = table->entries[i]; - int score = op_match(op, entry, next->comps); + int score = op_match(op, entry, &next->comps); if (score > best_score) { best_score = score; best_cpu_flags = table->cpu_flags; diff --git a/libswscale/ops_optimizer.c b/libswscale/ops_optimizer.c index 520069f859..bbdef052b1 100644 --- a/libswscale/ops_optimizer.c +++ b/libswscale/ops_optimizer.c @@ -188,7 +188,8 @@ static int exact_log2_q(const AVRational x) * If a linear operation can be reduced to a scalar multiplication, returns * the corresponding scaling factor, or 0 otherwise. */ -static bool extract_scalar(const SwsLinearOp *c, SwsComps prev, SwsComps next, +static bool extract_scalar(const SwsLinearOp *c, + const SwsComps *prev, const SwsComps *next, SwsConst *out_scale) { SwsConst scale = {0}; @@ -199,7 +200,7 @@ static bool extract_scalar(const SwsLinearOp *c, SwsComps prev, SwsComps next, for (int i = 0; i < 4; i++) { const AVRational s = c->m[i][i]; - if ((prev.flags[i] & SWS_COMP_ZERO) || next.unused[i]) + if ((prev->flags[i] & SWS_COMP_ZERO) || next->unused[i]) continue; if (scale.q.den && av_cmp_q(s, scale.q)) return false; @@ -212,7 +213,7 @@ static bool extract_scalar(const SwsLinearOp *c, SwsComps prev, SwsComps next, } /* Extracts an integer clear operation (subset) from the given linear op. */ -static bool extract_constant_rows(SwsLinearOp *c, SwsComps prev, +static bool extract_constant_rows(SwsLinearOp *c, const SwsComps *prev, SwsConst *out_clear) { SwsConst clear = {0}; @@ -222,7 +223,7 @@ static bool extract_constant_rows(SwsLinearOp *c, SwsComps prev, bool const_row = c->m[i][4].den == 1; /* offset is integer */ for (int j = 0; j < 4; j++) { const_row &= c->m[i][j].num == 0 || /* scalar is zero */ - (prev.flags[j] & SWS_COMP_ZERO); /* input is zero */ + (prev->flags[j] & SWS_COMP_ZERO); /* input is zero */ } if (const_row && (c->mask & SWS_MASK_ROW(i))) { clear.q4[i] = c->m[i][4]; @@ -240,7 +241,8 @@ static bool extract_constant_rows(SwsLinearOp *c, SwsComps prev, /* Unswizzle a linear operation by aligning single-input rows with * their corresponding diagonal */ -static bool extract_swizzle(SwsLinearOp *op, SwsComps prev, SwsSwizzleOp *out_swiz) +static bool extract_swizzle(SwsLinearOp *op, const SwsComps *prev, + SwsSwizzleOp *out_swiz) { SwsSwizzleOp swiz = SWS_SWIZZLE(0, 1, 2, 3); SwsLinearOp c = *op; @@ -249,7 +251,7 @@ static bool extract_swizzle(SwsLinearOp *op, SwsComps prev, SwsSwizzleOp *out_sw uint32_t nonzero = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - if (!c.m[i][j].num || (prev.flags[j] & SWS_COMP_ZERO)) + if (!c.m[i][j].num || (prev->flags[j] & SWS_COMP_ZERO)) continue; nonzero |= SWS_MASK(i, j); } @@ -274,7 +276,7 @@ static bool extract_swizzle(SwsLinearOp *op, SwsComps prev, SwsSwizzleOp *out_sw if (swiz.mask == SWS_SWIZZLE(0, 1, 2, 3).mask) return false; /* no swizzle was identified */ - c.mask = ff_sws_linear_mask(c); + c.mask = ff_sws_linear_mask(&c); *out_swiz = swiz; *op = c; return true; @@ -558,7 +560,7 @@ retry: op->lin.m[i][j] = sum; } } - op->lin.mask = ff_sws_linear_mask(op->lin); + op->lin.mask = ff_sws_linear_mask(&op->lin); ff_sws_op_list_remove_at(ops, n + 1, 1); goto retry; } @@ -586,7 +588,7 @@ retry: } /* Convert constant rows to explicit clear instruction */ - if (extract_constant_rows(&op->lin, prev->comps, &c)) { + if (extract_constant_rows(&op->lin, &prev->comps, &c)) { RET(ff_sws_op_list_insert_at(ops, n + 1, &(SwsOp) { .op = SWS_OP_CLEAR, .type = op->type, @@ -597,14 +599,14 @@ retry: } /* Multiplication by scalar constant */ - if (extract_scalar(&op->lin, prev->comps, next->comps, &c)) { + if (extract_scalar(&op->lin, &prev->comps, &next->comps, &c)) { op->op = SWS_OP_SCALE; op->c = c; goto retry; } /* Swizzle by fixed pattern */ - if (extract_swizzle(&op->lin, prev->comps, &swizzle)) { + if (extract_swizzle(&op->lin, &prev->comps, &swizzle)) { RET(ff_sws_op_list_insert_at(ops, n, &(SwsOp) { .op = SWS_OP_SWIZZLE, .type = op->type, -- 2.52.0 >From 4933927afff85c885af2e99da36d35e69e4afc66 Mon Sep 17 00:00:00 2001 From: Ramiro Polla <[email protected]> Date: Mon, 16 Mar 2026 16:54:32 +0100 Subject: [PATCH 4/4] swscale: change ff_fmt_from_frame() to write into an output pointer ... instead of return an SwsFormat by value. --- libswscale/format.c | 98 +++++++++++++++++++------------------- libswscale/format.h | 2 +- libswscale/swscale.c | 5 +- libswscale/tests/sws_ops.c | 5 +- 4 files changed, 56 insertions(+), 54 deletions(-) diff --git a/libswscale/format.c b/libswscale/format.c index b82d5a65dd..58bfe1220f 100644 --- a/libswscale/format.c +++ b/libswscale/format.c @@ -309,7 +309,7 @@ int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt) * This function also sanitizes and strips the input data, removing irrelevant * fields for certain formats. */ -SwsFormat ff_fmt_from_frame(const AVFrame *frame, int field) +void ff_fmt_from_frame(SwsFormat *fmt, const AVFrame *frame, int field) { const AVColorPrimariesDesc *primaries; AVFrameSideData *sd; @@ -327,7 +327,7 @@ SwsFormat ff_fmt_from_frame(const AVFrame *frame, int field) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); - SwsFormat fmt = { + *fmt = (SwsFormat) { .width = frame->width, .height = frame->height, .format = format, @@ -342,28 +342,28 @@ SwsFormat ff_fmt_from_frame(const AVFrame *frame, int field) }, }; - av_assert1(fmt.width > 0); - av_assert1(fmt.height > 0); - av_assert1(fmt.format != AV_PIX_FMT_NONE); + av_assert1(fmt->width > 0); + av_assert1(fmt->height > 0); + av_assert1(fmt->format != AV_PIX_FMT_NONE); av_assert0(desc); if (desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_BAYER)) { /* RGB-like family */ - fmt.csp = AVCOL_SPC_RGB; - fmt.range = AVCOL_RANGE_JPEG; + fmt->csp = AVCOL_SPC_RGB; + fmt->range = AVCOL_RANGE_JPEG; } else if (desc->flags & AV_PIX_FMT_FLAG_XYZ) { - fmt.csp = AVCOL_SPC_UNSPECIFIED; - fmt.color = (SwsColor) { + fmt->csp = AVCOL_SPC_UNSPECIFIED; + fmt->color = (SwsColor) { .prim = AVCOL_PRI_BT709, /* swscale currently hard-codes this XYZ matrix */ .trc = AVCOL_TRC_SMPTE428, }; } else if (desc->nb_components < 3) { /* Grayscale formats */ - fmt.color.prim = AVCOL_PRI_UNSPECIFIED; - fmt.csp = AVCOL_SPC_UNSPECIFIED; + fmt->color.prim = AVCOL_PRI_UNSPECIFIED; + fmt->csp = AVCOL_SPC_UNSPECIFIED; if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) - fmt.range = AVCOL_RANGE_UNSPECIFIED; + fmt->range = AVCOL_RANGE_UNSPECIFIED; else - fmt.range = AVCOL_RANGE_JPEG; // FIXME: this restriction should be lifted + fmt->range = AVCOL_RANGE_JPEG; // FIXME: this restriction should be lifted } switch (frame->format) { @@ -372,49 +372,49 @@ SwsFormat ff_fmt_from_frame(const AVFrame *frame, int field) case AV_PIX_FMT_YUVJ422P: case AV_PIX_FMT_YUVJ444P: case AV_PIX_FMT_YUVJ440P: - fmt.range = AVCOL_RANGE_JPEG; + fmt->range = AVCOL_RANGE_JPEG; break; } if (!desc->log2_chroma_w && !desc->log2_chroma_h) - fmt.loc = AVCHROMA_LOC_UNSPECIFIED; + fmt->loc = AVCHROMA_LOC_UNSPECIFIED; if (frame->flags & AV_FRAME_FLAG_INTERLACED) { - fmt.height = (fmt.height + (field == FIELD_TOP)) >> 1; - fmt.interlaced = 1; + fmt->height = (fmt->height + (field == FIELD_TOP)) >> 1; + fmt->interlaced = 1; } /* Set luminance and gamut information */ - fmt.color.min_luma = av_make_q(0, 1); - switch (fmt.color.trc) { + fmt->color.min_luma = av_make_q(0, 1); + switch (fmt->color.trc) { case AVCOL_TRC_SMPTE2084: - fmt.color.max_luma = av_make_q(10000, 1); break; + fmt->color.max_luma = av_make_q(10000, 1); break; case AVCOL_TRC_ARIB_STD_B67: - fmt.color.max_luma = av_make_q( 1000, 1); break; /* HLG reference display */ + fmt->color.max_luma = av_make_q( 1000, 1); break; /* HLG reference display */ default: - fmt.color.max_luma = av_make_q( 203, 1); break; /* SDR reference brightness */ + fmt->color.max_luma = av_make_q( 203, 1); break; /* SDR reference brightness */ } - primaries = av_csp_primaries_desc_from_id(fmt.color.prim); + primaries = av_csp_primaries_desc_from_id(fmt->color.prim); if (primaries) - fmt.color.gamut = primaries->prim; + fmt->color.gamut = primaries->prim; if ((sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA))) { const AVMasteringDisplayMetadata *mdm = (const AVMasteringDisplayMetadata *) sd->data; if (mdm->has_luminance) { - fmt.color.min_luma = mdm->min_luminance; - fmt.color.max_luma = mdm->max_luminance; + fmt->color.min_luma = mdm->min_luminance; + fmt->color.max_luma = mdm->max_luminance; } if (mdm->has_primaries) { /* Ignore mastering display white point as it has no bearance on * the underlying content */ - fmt.color.gamut.r.x = mdm->display_primaries[0][0]; - fmt.color.gamut.r.y = mdm->display_primaries[0][1]; - fmt.color.gamut.g.x = mdm->display_primaries[1][0]; - fmt.color.gamut.g.y = mdm->display_primaries[1][1]; - fmt.color.gamut.b.x = mdm->display_primaries[2][0]; - fmt.color.gamut.b.y = mdm->display_primaries[2][1]; + fmt->color.gamut.r.x = mdm->display_primaries[0][0]; + fmt->color.gamut.r.y = mdm->display_primaries[0][1]; + fmt->color.gamut.g.x = mdm->display_primaries[1][0]; + fmt->color.gamut.g.y = mdm->display_primaries[1][1]; + fmt->color.gamut.b.x = mdm->display_primaries[2][0]; + fmt->color.gamut.b.y = mdm->display_primaries[2][1]; } } @@ -435,16 +435,16 @@ SwsFormat ff_fmt_from_frame(const AVFrame *frame, int field) if (maxrgb.num > 0) { /* Estimate true luminance from MaxSCL */ - const AVLumaCoefficients *luma = av_csp_luma_coeffs_from_avcsp(fmt.csp); + const AVLumaCoefficients *luma = av_csp_luma_coeffs_from_avcsp(fmt->csp); if (!luma) goto skip_hdr10; - fmt.color.frame_peak = av_add_q(av_mul_q(luma->cr, pars->maxscl[0]), - av_add_q(av_mul_q(luma->cg, pars->maxscl[1]), - av_mul_q(luma->cb, pars->maxscl[2]))); + fmt->color.frame_peak = av_add_q(av_mul_q(luma->cr, pars->maxscl[0]), + av_add_q(av_mul_q(luma->cg, pars->maxscl[1]), + av_mul_q(luma->cb, pars->maxscl[2]))); /* Scale the scene average brightness by the ratio between the * maximum luminance and the MaxRGB values */ - fmt.color.frame_avg = av_mul_q(pars->average_maxrgb, - av_div_q(fmt.color.frame_peak, maxrgb)); + fmt->color.frame_avg = av_mul_q(pars->average_maxrgb, + av_div_q(fmt->color.frame_peak, maxrgb)); } else { /** * Calculate largest value from histogram to use as fallback for @@ -456,22 +456,20 @@ SwsFormat ff_fmt_from_frame(const AVFrame *frame, int field) const AVRational pct = pars->distribution_maxrgb[i].percentile; if (av_cmp_q(pct, maxrgb) > 0) maxrgb = pct; - fmt.color.frame_peak = maxrgb; - fmt.color.frame_avg = pars->average_maxrgb; + fmt->color.frame_peak = maxrgb; + fmt->color.frame_avg = pars->average_maxrgb; } } /* Rescale to nits */ - fmt.color.frame_peak = av_mul_q(nits, fmt.color.frame_peak); - fmt.color.frame_avg = av_mul_q(nits, fmt.color.frame_avg); + fmt->color.frame_peak = av_mul_q(nits, fmt->color.frame_peak); + fmt->color.frame_avg = av_mul_q(nits, fmt->color.frame_avg); } skip_hdr10: /* PQ is always scaled down to absolute zero, so ignore mastering metadata */ - if (fmt.color.trc == AVCOL_TRC_SMPTE2084) - fmt.color.min_luma = av_make_q(0, 1); - - return fmt; + if (fmt->color.trc == AVCOL_TRC_SMPTE2084) + fmt->color.min_luma = av_make_q(0, 1); } static int infer_prim_ref(SwsColor *csp, const SwsColor *ref) @@ -612,7 +610,8 @@ int ff_test_fmt(const SwsFormat *fmt, int output) int sws_test_frame(const AVFrame *frame, int output) { for (int field = 0; field < 2; field++) { - const SwsFormat fmt = ff_fmt_from_frame(frame, field); + SwsFormat fmt; + ff_fmt_from_frame(&fmt, frame, field); if (!ff_test_fmt(&fmt, output)) return 0; if (!fmt.interlaced) @@ -625,8 +624,9 @@ int sws_test_frame(const AVFrame *frame, int output) int sws_is_noop(const AVFrame *dst, const AVFrame *src) { for (int field = 0; field < 2; field++) { - SwsFormat dst_fmt = ff_fmt_from_frame(dst, field); - SwsFormat src_fmt = ff_fmt_from_frame(src, field); + SwsFormat dst_fmt, src_fmt; + ff_fmt_from_frame(&dst_fmt, dst, field); + ff_fmt_from_frame(&src_fmt, src, field); if (!ff_fmt_equal(&dst_fmt, &src_fmt)) return 0; if (!dst_fmt.interlaced) diff --git a/libswscale/format.h b/libswscale/format.h index d66851893f..793c823457 100644 --- a/libswscale/format.h +++ b/libswscale/format.h @@ -104,7 +104,7 @@ static inline void ff_fmt_clear(SwsFormat *fmt) * This function also sanitizes and strips the input data, removing irrelevant * fields for certain formats. */ -SwsFormat ff_fmt_from_frame(const AVFrame *frame, int field); +void ff_fmt_from_frame(SwsFormat *fmt, const AVFrame *frame, int field); static inline int ff_color_equal(const SwsColor *c1, const SwsColor *c2) { diff --git a/libswscale/swscale.c b/libswscale/swscale.c index b2090209d4..0102a5d5e1 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -1460,8 +1460,9 @@ int sws_frame_setup(SwsContext *ctx, const AVFrame *dst, const AVFrame *src) } for (int field = 0; field < 2; field++) { - SwsFormat src_fmt = ff_fmt_from_frame(src, field); - SwsFormat dst_fmt = ff_fmt_from_frame(dst, field); + SwsFormat src_fmt, dst_fmt; + ff_fmt_from_frame(&src_fmt, src, field); + ff_fmt_from_frame(&dst_fmt, dst, field); int src_ok, dst_ok; if ((src->flags ^ dst->flags) & AV_FRAME_FLAG_INTERLACED) { diff --git a/libswscale/tests/sws_ops.c b/libswscale/tests/sws_ops.c index 504fc34f6b..f144d95003 100644 --- a/libswscale/tests/sws_ops.c +++ b/libswscale/tests/sws_ops.c @@ -32,10 +32,11 @@ static int run_test(SwsContext *const ctx, AVFrame *frame, const AVPixFmtDescriptor *const dst_desc) { /* Reuse ff_fmt_from_frame() to ensure correctly sanitized metadata */ + SwsFormat src, dst; frame->format = av_pix_fmt_desc_get_id(src_desc); - SwsFormat src = ff_fmt_from_frame(frame, 0); + ff_fmt_from_frame(&src, frame, 0); frame->format = av_pix_fmt_desc_get_id(dst_desc); - SwsFormat dst = ff_fmt_from_frame(frame, 0); + ff_fmt_from_frame(&dst, frame, 0); bool incomplete = ff_infer_colors(&src.color, &dst.color); SwsOpList *ops = ff_sws_op_list_alloc(); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
