You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-04 22:03:09 +02:00
avfilter/vf_overlay: Use correct alpha when > 8 bits
When chroma subsampling is in use, the filter averages the corresponding (non subsampled) alpha values to get the actual alpha value. When vertical subsampling is in use, the next line is accessed via a[src->linesize[3]], yet a is an uint16_t* for >8 bit formats and linesize is always in bytes, so that this actually uses the second line below the current one. This is fixed in this commit. No FATE test needed updates, because the filter-overlay-yuv420p10 and filter-overlay-yuv444p10 tests use a yuv420p test file that has constant opacity after conversion to yuva. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
@ -353,6 +353,9 @@ static int config_output(AVFilterLink *outlink)
|
|||||||
// ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)) is a faster version of: 255 * (x + y)
|
// ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)) is a faster version of: 255 * (x + y)
|
||||||
#define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)))
|
#define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)))
|
||||||
|
|
||||||
|
#define PTR_ADD(TYPE, ptr, byte_addend) ((TYPE*)((uint8_t*)ptr + (byte_addend)))
|
||||||
|
#define CPTR_ADD(TYPE, ptr, byte_addend) ((const TYPE*)((const uint8_t*)ptr + (byte_addend)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blend image in src to destination buffer dst at position (x, y).
|
* Blend image in src to destination buffer dst at position (x, y).
|
||||||
*/
|
*/
|
||||||
@ -511,13 +514,14 @@ static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext
|
|||||||
\
|
\
|
||||||
/* average alpha for color components, improve quality */ \
|
/* average alpha for color components, improve quality */ \
|
||||||
if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \
|
if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \
|
||||||
alpha = (a[0] + a[src->linesize[3]] + \
|
const T *next_line = CPTR_ADD(T, a, src->linesize[3]); \
|
||||||
a[1] + a[src->linesize[3]+1]) >> 2; \
|
alpha = (a[0] + next_line[0] + \
|
||||||
|
a[1] + next_line[1]) >> 2; \
|
||||||
} else if (hsub || vsub) { \
|
} else if (hsub || vsub) { \
|
||||||
alpha_h = hsub && k+1 < src_wp ? \
|
alpha_h = hsub && k+1 < src_wp ? \
|
||||||
(a[0] + a[1]) >> 1 : a[0]; \
|
(a[0] + a[1]) >> 1 : a[0]; \
|
||||||
alpha_v = vsub && j+1 < src_hp ? \
|
alpha_v = vsub && j+1 < src_hp ? \
|
||||||
(a[0] + a[src->linesize[3]]) >> 1 : a[0]; \
|
(a[0] + *CPTR_ADD(T, a, src->linesize[3])) >> 1 : a[0]; \
|
||||||
alpha = (alpha_v + alpha_h) >> 1; \
|
alpha = (alpha_v + alpha_h) >> 1; \
|
||||||
} else \
|
} else \
|
||||||
alpha = a[0]; \
|
alpha = a[0]; \
|
||||||
@ -527,13 +531,14 @@ static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext
|
|||||||
/* average alpha for color components, improve quality */ \
|
/* average alpha for color components, improve quality */ \
|
||||||
uint8_t alpha_d; \
|
uint8_t alpha_d; \
|
||||||
if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \
|
if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \
|
||||||
alpha_d = (da[0] + da[dst->linesize[3]] + \
|
const T *next_line = CPTR_ADD(T, da, dst->linesize[3]); \
|
||||||
da[1] + da[dst->linesize[3]+1]) >> 2; \
|
alpha_d = (da[0] + next_line[0] + \
|
||||||
|
da[1] + next_line[1]) >> 2; \
|
||||||
} else if (hsub || vsub) { \
|
} else if (hsub || vsub) { \
|
||||||
alpha_h = hsub && k+1 < src_wp ? \
|
alpha_h = hsub && k+1 < src_wp ? \
|
||||||
(da[0] + da[1]) >> 1 : da[0]; \
|
(da[0] + da[1]) >> 1 : da[0]; \
|
||||||
alpha_v = vsub && j+1 < src_hp ? \
|
alpha_v = vsub && j+1 < src_hp ? \
|
||||||
(da[0] + da[dst->linesize[3]]) >> 1 : da[0]; \
|
(da[0] + *CPTR_ADD(T, da, dst->linesize[3])) >> 1 : da[0]; \
|
||||||
alpha_d = (alpha_v + alpha_h) >> 1; \
|
alpha_d = (alpha_v + alpha_h) >> 1; \
|
||||||
} else \
|
} else \
|
||||||
alpha_d = da[0]; \
|
alpha_d = da[0]; \
|
||||||
|
Reference in New Issue
Block a user