mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-10-28 10:04:37 +08:00
avfilter/blend: clip expression output to pixel depth
Clip integer expression results in the double domain before storing them. This keeps high-bit-depth samples within their declared range and gives NaN and infinities defined behavior while preserving float formats. Fixes issue #24121.
This commit is contained in:
1 parent
ade01193a1
commit
21bbd98e7b
4 files changed
+18
-5
No files matched your search
@@ -78,6 +78,7 @@ typedef struct SliceParams {
|
||||
typedef struct FilterParams {
|
||||
enum BlendMode mode;
|
||||
double opacity;
|
||||
unsigned max_value;
|
||||
AVExpr **e;
|
||||
char *expr_str;
|
||||
void (*blend)(const uint8_t *top, ptrdiff_t top_linesize,
|
||||
|
||||
@@ -129,7 +129,7 @@ static const AVOption blend_options[] = {
|
||||
|
||||
FRAMESYNC_DEFINE_CLASS(blend, BlendContext, fs);
|
||||
|
||||
#define DEFINE_BLEND_EXPR(type, name, div) \
|
||||
#define DEFINE_BLEND_EXPR(type, name, div, clip) \
|
||||
static void blend_expr_## name(const uint8_t *_top, ptrdiff_t top_linesize, \
|
||||
const uint8_t *_bottom, ptrdiff_t bottom_linesize, \
|
||||
uint8_t *_dst, ptrdiff_t dst_linesize, \
|
||||
@@ -153,7 +153,8 @@ static void blend_expr_## name(const uint8_t *_top, ptrdiff_t top_linesize,
|
||||
values[VAR_X] = x; \
|
||||
values[VAR_TOP] = values[VAR_A] = top[x]; \
|
||||
values[VAR_BOTTOM] = values[VAR_B] = bottom[x]; \
|
||||
dst[x] = av_expr_eval(e, values, NULL); \
|
||||
double value = av_expr_eval(e, values, NULL); \
|
||||
dst[x] = clip ? av_clipd(value, 0, param->max_value) : value; \
|
||||
} \
|
||||
dst += dst_linesize; \
|
||||
top += top_linesize; \
|
||||
@@ -161,9 +162,9 @@ static void blend_expr_## name(const uint8_t *_top, ptrdiff_t top_linesize,
|
||||
} \
|
||||
}
|
||||
|
||||
DEFINE_BLEND_EXPR(uint8_t, 8bit, 1)
|
||||
DEFINE_BLEND_EXPR(uint16_t, 16bit, 2)
|
||||
DEFINE_BLEND_EXPR(float, 32bit, 4)
|
||||
DEFINE_BLEND_EXPR(uint8_t, 8bit, 1, 1)
|
||||
DEFINE_BLEND_EXPR(uint16_t, 16bit, 2, 1)
|
||||
DEFINE_BLEND_EXPR(float, 32bit, 4, 0)
|
||||
|
||||
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
|
||||
{
|
||||
@@ -306,6 +307,8 @@ static int config_params(AVFilterContext *ctx)
|
||||
for (int plane = 0; plane < FF_ARRAY_ELEMS(s->params); plane++) {
|
||||
FilterParams *param = &s->params[plane];
|
||||
|
||||
param->max_value = UINT32_MAX >> (32 - s->depth);
|
||||
|
||||
if (s->all_mode >= 0)
|
||||
param->mode = s->all_mode;
|
||||
if (s->all_opacity < 1)
|
||||
|
||||
@@ -382,6 +382,9 @@ FATE_FILTER_VSYNTH_PGMYUV-$(CONFIG_SWAPRECT_FILTER) += $(FATE_SWAPRECT)
|
||||
FATE_FILTER_VSYNTH_PGMYUV-$(CONFIG_TBLEND_FILTER) += fate-filter-tblend
|
||||
fate-filter-tblend: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf tblend=all_mode=difference128
|
||||
|
||||
FATE_FILTER-$(call FILTERFRAMECRC, BLEND FORMAT NULLSRC SCALE SPLIT) += fate-filter-blend-expr-clipping
|
||||
fate-filter-blend-expr-clipping: CMD = framecrc -lavfi "nullsrc=s=1x1:d=1:r=1,format=gray10,split[a][b];[a][b]blend=c0_expr=1024,scale" -pix_fmt gray10le
|
||||
|
||||
FATE_FILTER_VSYNTH_PGMYUV-$(CONFIG_TELECINE_FILTER) += fate-filter-telecine
|
||||
fate-filter-telecine: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf telecine
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#tb 0: 1/1
|
||||
#media_type 0: video
|
||||
#codec_id 0: rawvideo
|
||||
#dimensions 0: 1x1
|
||||
#sar 0: 1/1
|
||||
0, 0, 0, 1, 2, 0x02010102
|
||||
Reference in new issue
Block a user