1
0
mirror of https://git.ffmpeg.org/ffmpeg.git synced 2026-10-24 02:09:03 +03:00

swscale/filters: add ability to set a virtual output size

Odd-size luma planes are not exact multiples of the chroma plane; but the
sample grid is still matched as though it were. We need to account for this
when translating a luma sample to the corresponding chroma sample coordinates.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Niklas Haas <git@haasn.dev>
(cherry-picked from commit fa1ca69a8b)
Signed-off-by: Marvin Scholz <epirat07@gmail.com>
This commit is contained in:
Niklas Haas
2026-06-19 15:36:08 +02:00
committed by Marvin Scholz
parent bce55bc471
commit 6c184597b2
2 changed files with 21 additions and 1 deletions

View File

@@ -192,7 +192,11 @@ int ff_sws_filter_generate(void *log, const SwsFilterParams *params,
if (scaler == SWS_SCALE_AUTO)
scaler = SWS_SCALE_BICUBIC;
const double ratio = (double) params->dst_size / params->src_size;
double virtual_size = params->virtual_size;
if (!virtual_size)
virtual_size = params->dst_size;
const double ratio = virtual_size / params->src_size;
double stretch = 1.0;
if (ratio < 1.0 && scaler != SWS_SCALE_POINT) {
/* Widen filter for downscaling (anti-aliasing) */
@@ -241,6 +245,7 @@ int ff_sws_filter_generate(void *log, const SwsFilterParams *params,
memcpy(filter->name, fun.name, sizeof(filter->name));
filter->src_size = params->src_size;
filter->dst_size = params->dst_size;
filter->virtual_size = virtual_size;
filter->offset = params->offset;
filter->filter_size = filter_size;
if (filter->filter_size == 1)

View File

@@ -73,6 +73,20 @@ typedef struct SwsFilterParams {
int src_size;
int dst_size;
/**
* The virtual output size. If zero, this is assumed to be the same as
* `dst_size`. Matters for e.g. chroma subsampling, where the the luma
* plane may be smaller than the dst_size. For example, a 99x99 input
* image has a chroma size of 50x50, which would be 100x100 after
* chroma upscaling; but is sampled only at 99x99 resolution. In this
* instance, dst_size is 99x99 and virtual_size is 100x100.
*
* The upscaling offset from this shift is implicit and does not need
* to be accounted for in `offset`. In other words, `offset` is taken
* relative to the virtual size, not the sampled size.
*/
double virtual_size;
/**
* The sample offset, in units of input pixels. This is added onto all
* sampled coordinates directly, i.e. a value of offset = 1.0 would shift
@@ -111,6 +125,7 @@ typedef struct SwsFilterWeights {
*/
int src_size;
int dst_size;
double virtual_size;
double offset;
/**