mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2026-03-13 09:00:40 +08:00
swscale/utils: separate luma and chroma scaler selection
Pre-requisite for adding support for configuring these independently. Sponsored-by: Sovereign Tech Fund Signed-off-by: Niklas Haas <git@haasn.dev>
This commit is contained in:
@@ -196,7 +196,7 @@ static const ScaleAlgorithm scale_algorithms[] = {
|
||||
static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
|
||||
int *outFilterSize, int xInc, int srcW,
|
||||
int dstW, int filterAlign, int one,
|
||||
int flags, int cpu_flags,
|
||||
int scaler, int flags, int cpu_flags,
|
||||
SwsVector *srcFilter, SwsVector *dstFilter,
|
||||
double param[SWS_NUM_SCALER_PARAMS], int srcPos, int dstPos)
|
||||
{
|
||||
@@ -225,7 +225,7 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
|
||||
filter[i * filterSize] = fone;
|
||||
(*filterPos)[i] = i;
|
||||
}
|
||||
} else if (flags & SWS_POINT) { // lame looking point sampling mode
|
||||
} else if (scaler == SWS_POINT) { // lame looking point sampling mode
|
||||
int i;
|
||||
int64_t xDstInSrc;
|
||||
filterSize = 1;
|
||||
@@ -240,8 +240,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
|
||||
filter[i] = fone;
|
||||
xDstInSrc += xInc;
|
||||
}
|
||||
} else if ((xInc <= (1 << 16) && (flags & SWS_AREA)) ||
|
||||
(flags & SWS_FAST_BILINEAR)) { // bilinear upscale
|
||||
} else if ((xInc <= (1 << 16) && (scaler == SWS_AREA)) ||
|
||||
(scaler == SWS_FAST_BILINEAR)) { // bilinear upscale
|
||||
int i;
|
||||
int64_t xDstInSrc;
|
||||
filterSize = 2;
|
||||
@@ -269,12 +269,12 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
|
||||
int sizeFactor = -1;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(scale_algorithms); i++) {
|
||||
if (flags & scale_algorithms[i].flag && scale_algorithms[i].size_factor > 0) {
|
||||
if (scaler == scale_algorithms[i].flag && scale_algorithms[i].size_factor > 0) {
|
||||
sizeFactor = scale_algorithms[i].size_factor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flags & SWS_LANCZOS)
|
||||
if (scaler == SWS_LANCZOS)
|
||||
sizeFactor = param[0] != SWS_PARAM_DEFAULT ? ceil(2 * param[0]) : 6;
|
||||
av_assert0(sizeFactor > 0);
|
||||
|
||||
@@ -308,7 +308,7 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
|
||||
d = d * dstW / srcW;
|
||||
floatd = d * (1.0 / (1 << 30));
|
||||
|
||||
if (flags & SWS_BICUBIC) {
|
||||
if (scaler == SWS_BICUBIC) {
|
||||
int64_t B = (param[0] != SWS_PARAM_DEFAULT ? param[0] : 0) * (1 << 24);
|
||||
int64_t C = (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1 << 24);
|
||||
|
||||
@@ -329,7 +329,7 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
|
||||
(8 * B + 24 * C) * (1 << 30);
|
||||
}
|
||||
coeff /= (1LL<<54)/fone;
|
||||
} else if (flags & SWS_X) {
|
||||
} else if (scaler == SWS_X) {
|
||||
double A = param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0;
|
||||
double c;
|
||||
|
||||
@@ -342,7 +342,7 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
|
||||
else
|
||||
c = pow(c, A);
|
||||
coeff = (c * 0.5 + 0.5) * fone;
|
||||
} else if (flags & SWS_AREA) {
|
||||
} else if (scaler == SWS_AREA) {
|
||||
int64_t d2 = d - (1 << 29);
|
||||
if (d2 * xInc < -(1LL << (29 + 16)))
|
||||
coeff = 1.0 * (1LL << (30 + 16));
|
||||
@@ -351,23 +351,23 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
|
||||
else
|
||||
coeff = 0.0;
|
||||
coeff *= fone >> (30 + 16);
|
||||
} else if (flags & SWS_GAUSS) {
|
||||
} else if (scaler == SWS_GAUSS) {
|
||||
double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
|
||||
coeff = exp2(-p * floatd * floatd) * fone;
|
||||
} else if (flags & SWS_SINC) {
|
||||
} else if (scaler == SWS_SINC) {
|
||||
coeff = (d ? sin(floatd * M_PI) / (floatd * M_PI) : 1.0) * fone;
|
||||
} else if (flags & SWS_LANCZOS) {
|
||||
} else if (scaler == SWS_LANCZOS) {
|
||||
double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;
|
||||
coeff = (d ? sin(floatd * M_PI) * sin(floatd * M_PI / p) /
|
||||
(floatd * floatd * M_PI * M_PI / p) : 1.0) * fone;
|
||||
if (floatd > p)
|
||||
coeff = 0;
|
||||
} else if (flags & SWS_BILINEAR) {
|
||||
} else if (scaler == SWS_BILINEAR) {
|
||||
coeff = (1 << 30) - d;
|
||||
if (coeff < 0)
|
||||
coeff = 0;
|
||||
coeff *= fone >> 30;
|
||||
} else if (flags & SWS_SPLINE) {
|
||||
} else if (scaler == SWS_SPLINE) {
|
||||
double p = -2.196152422706632;
|
||||
coeff = getSplineCoeff(1.0, 0.0, p, -p - 1.0, floatd) * fone;
|
||||
} else {
|
||||
@@ -1191,17 +1191,30 @@ av_cold int ff_sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter,
|
||||
/* provide a default scaler if not set by caller */
|
||||
if (!i) {
|
||||
if (dstW < srcW && dstH < srcH)
|
||||
flags |= SWS_BICUBIC;
|
||||
i = SWS_BICUBIC;
|
||||
else if (dstW > srcW && dstH > srcH)
|
||||
flags |= SWS_BICUBIC;
|
||||
i = SWS_BICUBIC;
|
||||
else
|
||||
flags |= SWS_BICUBIC;
|
||||
i = SWS_BICUBIC;
|
||||
flags |= i;
|
||||
sws->flags = flags;
|
||||
} else if (i & (i - 1)) {
|
||||
av_log(c, AV_LOG_ERROR,
|
||||
"Exactly one scaler algorithm must be chosen, got %X\n", i);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (i == SWS_FAST_BILINEAR) {
|
||||
if (srcW < 8 || dstW <= 8) {
|
||||
i = SWS_BILINEAR;
|
||||
flags ^= SWS_FAST_BILINEAR | i;
|
||||
sws->flags = flags;
|
||||
}
|
||||
}
|
||||
|
||||
int lum_scaler = i == SWS_BICUBLIN ? SWS_BICUBIC : i;
|
||||
int chr_scaler = i == SWS_BICUBLIN ? SWS_BILINEAR : i;
|
||||
|
||||
/* sanity check */
|
||||
if (srcW < 1 || srcH < 1 || dstW < 1 || dstH < 1) {
|
||||
/* FIXME check if these are enough and try to lower them after
|
||||
@@ -1210,12 +1223,6 @@ av_cold int ff_sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter,
|
||||
srcW, srcH, dstW, dstH);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (flags & SWS_FAST_BILINEAR) {
|
||||
if (srcW < 8 || dstW <= 8) {
|
||||
flags ^= SWS_FAST_BILINEAR | SWS_BILINEAR;
|
||||
sws->flags = flags;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dstFilter)
|
||||
dstFilter = &dummyFilter;
|
||||
@@ -1691,7 +1698,7 @@ av_cold int ff_sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter,
|
||||
if ((ret = initFilter(&c->hLumFilter, &c->hLumFilterPos,
|
||||
&c->hLumFilterSize, c->lumXInc,
|
||||
srcW, dstW, filterAlign, 1 << 14,
|
||||
(flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
|
||||
lum_scaler, flags,
|
||||
cpu_flags, srcFilter->lumH, dstFilter->lumH,
|
||||
sws->scaler_params,
|
||||
get_local_pos(c, 0, 0, 0),
|
||||
@@ -1702,7 +1709,7 @@ av_cold int ff_sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter,
|
||||
if ((ret = initFilter(&c->hChrFilter, &c->hChrFilterPos,
|
||||
&c->hChrFilterSize, c->chrXInc,
|
||||
c->chrSrcW, c->chrDstW, filterAlign, 1 << 14,
|
||||
(flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
|
||||
chr_scaler, flags,
|
||||
cpu_flags, srcFilter->chrH, dstFilter->chrH,
|
||||
sws->scaler_params,
|
||||
get_local_pos(c, c->chrSrcHSubSample, sws->src_h_chr_pos, 0),
|
||||
@@ -1721,7 +1728,7 @@ av_cold int ff_sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter,
|
||||
|
||||
ret = initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize,
|
||||
c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
|
||||
(flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
|
||||
lum_scaler, flags,
|
||||
cpu_flags, srcFilter->lumV, dstFilter->lumV,
|
||||
sws->scaler_params,
|
||||
get_local_pos(c, 0, 0, 1),
|
||||
@@ -1732,7 +1739,7 @@ av_cold int ff_sws_init_single_context(SwsContext *sws, SwsFilter *srcFilter,
|
||||
if ((ret = initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize,
|
||||
c->chrYInc, c->chrSrcH, c->chrDstH,
|
||||
filterAlign, (1 << 12),
|
||||
(flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
|
||||
chr_scaler, flags,
|
||||
cpu_flags, srcFilter->chrV, dstFilter->chrV,
|
||||
sws->scaler_params,
|
||||
get_local_pos(c, c->chrSrcVSubSample, sws->src_v_chr_pos, 1),
|
||||
|
||||
Reference in New Issue
Block a user