This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 1f6dc79c807ab6044e8b4ef990386b2e9d9e918e Author: Niklas Haas <[email protected]> AuthorDate: Fri Jun 19 15:07:24 2026 +0200 Commit: Niklas Haas <[email protected]> CommitDate: Sat Jun 20 03:07:35 2026 +0200 swscale/format: factor out ff_sws_chroma_pos() helper Moved here from graph.c, as it's needed for the new chroma scaling code. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas <[email protected]> --- libswscale/format.c | 41 +++++++++++++++++++++++++++++++++++++ libswscale/format.h | 7 +++++++ libswscale/graph.c | 58 ++++++++++++----------------------------------------- 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/libswscale/format.c b/libswscale/format.c index a68565e8e5..0538ab9db4 100644 --- a/libswscale/format.c +++ b/libswscale/format.c @@ -1393,6 +1393,47 @@ linear_mat3(const AVRational m00, const AVRational m01, const AVRational m02, return c; } +void ff_sws_chroma_pos(const SwsFormat *fmt, bool *incomplete, + int *out_x_pos, int *out_y_pos) +{ + enum AVChromaLocation chroma_loc = fmt->loc; + const int sub_x = fmt->desc->log2_chroma_w; + const int sub_y = fmt->desc->log2_chroma_h; + int x_pos, y_pos; + + /* Explicitly default to center siting for compatibility with swscale */ + if (chroma_loc == AVCHROMA_LOC_UNSPECIFIED) { + chroma_loc = AVCHROMA_LOC_CENTER; + *incomplete |= sub_x || sub_y; + } + + /* av_chroma_location_enum_to_pos() always gives us values in the range from + * 0 to 256, but we need to adjust this to the true value range of the + * subsampling grid, which may be larger for h/v_sub > 1 */ + av_chroma_location_enum_to_pos(&x_pos, &y_pos, chroma_loc); + x_pos *= (1 << sub_x) - 1; + y_pos *= (1 << sub_y) - 1; + + /* Fix vertical chroma position for interlaced frames */ + if (sub_y && fmt->interlaced) { + /* When vertically subsampling, chroma samples are effectively only + * placed next to even rows. To access them from the odd field, we need + * to account for this shift by offsetting the distance of one luma row. + * + * For 4x vertical subsampling (v_sub == 2), they are only placed + * next to every *other* even row, so we need to shift by three luma + * rows to get to the chroma sample. */ + if (fmt->field == FIELD_BOTTOM) + y_pos += (256 << sub_y) - 256; + + /* Luma row distance is doubled for fields, so halve offsets */ + y_pos >>= 1; + } + + *out_x_pos = x_pos; + *out_y_pos = y_pos; +} + int ff_sws_decode_colors(SwsContext *ctx, SwsPixelType type, SwsOpList *ops, const SwsFormat *fmt, bool *incomplete) { diff --git a/libswscale/format.h b/libswscale/format.h index 9b852efd39..ea2ab7dc41 100644 --- a/libswscale/format.h +++ b/libswscale/format.h @@ -161,6 +161,13 @@ int ff_test_fmt(SwsBackend backends, const SwsFormat *fmt, int output); /* Returns true if the formats are incomplete, false otherwise */ bool ff_infer_colors(SwsColor *src, SwsColor *dst); +/** + * Wrapper around av_chroma_location_enum_to_pos() that accounts for + * the per-field offset introduced by interlacing. + */ +void ff_sws_chroma_pos(const SwsFormat *fmt, bool *incomplete, + int *out_xpos, int *out_ypos); + typedef struct SwsOpList SwsOpList; typedef enum SwsPixelType SwsPixelType; diff --git a/libswscale/graph.c b/libswscale/graph.c index 73df6b8907..a99cd7cadf 100644 --- a/libswscale/graph.c +++ b/libswscale/graph.c @@ -375,49 +375,6 @@ static void run_legacy_swscale(const SwsFrame *out, const SwsFrame *in, sws->src_h, out_data, out->linesize, y, h); } -static void get_chroma_pos(SwsGraph *graph, int *h_chr_pos, int *v_chr_pos, - const SwsFormat *fmt) -{ - enum AVChromaLocation chroma_loc = fmt->loc; - const int sub_x = fmt->desc->log2_chroma_w; - const int sub_y = fmt->desc->log2_chroma_h; - int x_pos, y_pos; - - /* Explicitly default to center siting for compatibility with swscale */ - if (chroma_loc == AVCHROMA_LOC_UNSPECIFIED) { - chroma_loc = AVCHROMA_LOC_CENTER; - graph->incomplete |= sub_x || sub_y; - } - - /* av_chroma_location_enum_to_pos() always gives us values in the range from - * 0 to 256, but we need to adjust this to the true value range of the - * subsampling grid, which may be larger for h/v_sub > 1 */ - av_chroma_location_enum_to_pos(&x_pos, &y_pos, chroma_loc); - x_pos *= (1 << sub_x) - 1; - y_pos *= (1 << sub_y) - 1; - - /* Fix vertical chroma position for interlaced frames */ - if (sub_y && fmt->interlaced) { - /* When vertically subsampling, chroma samples are effectively only - * placed next to even rows. To access them from the odd field, we need - * to account for this shift by offsetting the distance of one luma row. - * - * For 4x vertical subsampling (v_sub == 2), they are only placed - * next to every *other* even row, so we need to shift by three luma - * rows to get to the chroma sample. */ - if (fmt->field == FIELD_BOTTOM) - y_pos += (256 << sub_y) - 256; - - /* Luma row distance is doubled for fields, so halve offsets */ - y_pos >>= 1; - } - - /* Explicitly strip chroma offsets when not subsampling, because it - * interferes with the operation of flags like SWS_FULL_CHR_H_INP */ - *h_chr_pos = sub_x ? x_pos : -513; - *v_chr_pos = sub_y ? y_pos : -513; -} - static void legacy_chr_pos(SwsGraph *graph, int *chr_pos, int override, int *warned) { if (override == -513 || override == *chr_pos) @@ -582,8 +539,8 @@ static int add_legacy_sws_pass(SwsGraph *graph, const SwsFormat *src, sws->dst_h = dst->height; sws->dst_format = dst->format; sws->dst_range = dst->range == AVCOL_RANGE_JPEG; - get_chroma_pos(graph, &sws->src_h_chr_pos, &sws->src_v_chr_pos, src); - get_chroma_pos(graph, &sws->dst_h_chr_pos, &sws->dst_v_chr_pos, dst); + ff_sws_chroma_pos(src, &graph->incomplete, &sws->src_h_chr_pos, &sws->src_v_chr_pos); + ff_sws_chroma_pos(dst, &graph->incomplete, &sws->dst_h_chr_pos, &sws->dst_v_chr_pos); graph->incomplete |= src->range == AVCOL_RANGE_UNSPECIFIED; graph->incomplete |= dst->range == AVCOL_RANGE_UNSPECIFIED; @@ -594,6 +551,17 @@ static int add_legacy_sws_pass(SwsGraph *graph, const SwsFormat *src, legacy_chr_pos(graph, &sws->dst_h_chr_pos, ctx->dst_h_chr_pos, &warned); legacy_chr_pos(graph, &sws->dst_v_chr_pos, ctx->dst_v_chr_pos, &warned); + /* Explicitly strip chroma offsets when not subsampling, because it + * interferes with the operation of flags like SWS_FULL_CHR_H_INP */ + if (!src->desc->log2_chroma_w) + sws->src_h_chr_pos = -513; + if (!src->desc->log2_chroma_h) + sws->src_v_chr_pos = -513; + if (!dst->desc->log2_chroma_w) + sws->dst_h_chr_pos = -513; + if (!dst->desc->log2_chroma_h) + sws->dst_v_chr_pos = -513; + for (int i = 0; i < SWS_NUM_SCALER_PARAMS; i++) sws->scaler_params[i] = ctx->scaler_params[i]; _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
