swscale/ops: add subsampling shift to SwsOpExec

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Niklas Haas <git@haasn.dev>
This commit is contained in:
Niklas Haas 2026-02-27 10:30:00 +01:00 committed by Niklas Haas
parent 16ee3d8d99
commit 79334c8ca1
3 changed files with 21 additions and 4 deletions

View file

@ -982,24 +982,32 @@ static void op_pass_setup(const SwsImg *out_base, const SwsImg *in_base,
for (int i = 0; i < p->planes_in; i++) {
const int idx = p->idx_in[i];
const int sub_x = (idx == 1 || idx == 2) ? indesc->log2_chroma_w : 0;
const int chroma = idx == 1 || idx == 2;
const int sub_x = chroma ? indesc->log2_chroma_w : 0;
const int sub_y = chroma ? indesc->log2_chroma_h : 0;
const int plane_w = (aligned_w + sub_x) >> sub_x;
const int plane_pad = (comp->over_read + sub_x) >> sub_x;
const int plane_size = plane_w * p->pixel_bits_in >> 3;
if (comp->slice_align)
p->memcpy_in |= plane_size + plane_pad > in.linesize[i];
exec->in_stride[i] = in.linesize[i];
exec->in_sub_y[i] = sub_y;
exec->in_sub_x[i] = sub_x;
}
for (int i = 0; i < p->planes_out; i++) {
const int idx = p->idx_out[i];
const int sub_x = (idx == 1 || idx == 2) ? outdesc->log2_chroma_w : 0;
const int chroma = idx == 1 || idx == 2;
const int sub_x = chroma ? outdesc->log2_chroma_w : 0;
const int sub_y = chroma ? outdesc->log2_chroma_h : 0;
const int plane_w = (aligned_w + sub_x) >> sub_x;
const int plane_pad = (comp->over_write + sub_x) >> sub_x;
const int plane_size = plane_w * p->pixel_bits_out >> 3;
if (comp->slice_align)
p->memcpy_out |= plane_size + plane_pad > out.linesize[i];
exec->out_stride[i] = out.linesize[i];
exec->out_sub_y[i] = sub_y;
exec->out_sub_x[i] = sub_x;
}
/* Pre-fill pointer bump for the main section only; this value does not

View file

@ -76,13 +76,18 @@ typedef struct SwsOpExec {
int32_t block_size_in; /* Size of a block of pixels in bytes */
int32_t block_size_out;
/* Subsampling factors for each plane */
uint8_t in_sub_y[4], out_sub_y[4];
uint8_t in_sub_x[4], out_sub_x[4];
const AVFrame *src_frame_ptr;
const AVFrame *dst_frame_ptr;
} SwsOpExec;
static_assert(sizeof(SwsOpExec) == 24 * sizeof(void *) +
6 * sizeof(int32_t) +
2 * sizeof(void *),
6 * sizeof(int32_t) +
16 * sizeof(uint8_t) +
2 * sizeof(void *),
"SwsOpExec layout mismatch");
/**

View file

@ -137,6 +137,10 @@ struc SwsOpExec
.slice_h resd 1
.block_size_in resd 1
.block_size_out resd 1
.in_sub_y4 resb 4
.out_sub_y4 resb 4
.in_sub_x4 resb 4
.out_sub_x4 resb 4
.in_hwframe_ref resq 1
.out_hwframe_ref resq 1
endstruc