This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit c7a2646bc772b642167d9d2af3673fd50ae20015 Author: Ayose <[email protected]> AuthorDate: Fri Dec 5 14:19:49 2025 +0000 Commit: Marton Balint <[email protected]> CommitDate: Sun Jan 4 13:42:20 2026 +0000 avfilter/vf_drawvg: values from the p() function can be used as colors. To be able to reuse colors from the original frame, the last value returned by `p()` is tracked in the eval state, and if it is assigned to a variable, the original color components are copied to `color_vars`. Thus, commands like `setcolor` and `colorstop` can use those variables: setvar pixel (p(0, 0)) ... setcolor pixel `fate-filter-drawvg-video` now also verifies the `p()` function. Signed-off-by: Ayose <[email protected]> --- libavfilter/vf_drawvg.c | 49 ++++++++++++++++++++++++++++++++------ tests/fate/filter-video.mak | 9 +++---- tests/ref/fate/filter-drawvg-video | 2 +- tests/ref/lavf/drawvg.lines | 10 -------- tests/ref/lavf/drawvg.video | 13 ++++++++++ 5 files changed, 61 insertions(+), 22 deletions(-) diff --git a/libavfilter/vf_drawvg.c b/libavfilter/vf_drawvg.c index f89605185f..99280366f3 100644 --- a/libavfilter/vf_drawvg.c +++ b/libavfilter/vf_drawvg.c @@ -1443,6 +1443,12 @@ struct VGSEvalState { /// Colors stored in variables. cairo_color color_vars[USER_VAR_COUNT]; + /// Track last color read by the `p()` function. + struct { + double numeric; + uint8_t components[4]; + } last_fn_p_color; + /// State for each index available for the `randomg` function. FFSFC64 random_state[RANDOM_STATES]; @@ -1555,7 +1561,7 @@ static double vgs_fn_randomg(void *data, double arg) { /// /// If the coordinates are outside the frame, return NAN. static double vgs_fn_p(void* data, double x0, double y0) { - const struct VGSEvalState *state = (struct VGSEvalState *)data; + struct VGSEvalState *state = (struct VGSEvalState *)data; const AVFrame *frame = state->frame; if (frame == NULL || !isfinite(x0) || !isfinite(y0)) @@ -1575,8 +1581,6 @@ static double vgs_fn_p(void* data, double x0, double y0) { for (int c = 0; c < desc->nb_components; c++) { uint32_t pixel; - const int depth = desc->comp[c].depth; - av_read_image_line2( &pixel, (void*)frame->data, @@ -1589,14 +1593,35 @@ static double vgs_fn_p(void* data, double x0, double y0) { 4 // dst_element_size ); - if (depth != 8) { + const int depth = desc->comp[c].depth; + if (depth != 8) pixel = pixel * 255 / ((1 << depth) - 1); - } color[c] = pixel; } - return color[0] << 24 | color[1] << 16 | color[2] << 8 | color[3]; + // A common use-case of `p()` is to store its result in a variable, so it + // can be used later with commands like `setcolor` or `colorstop`: + // + // setvar pixel (p(0, 0)) + // ... + // setcolor pixel + // + // Since we can't pass custom values through `av_expr_eval`, we store the + // color in the `VGSEvalState` instance. Then, when a variable is assigned + // in `setvar`, it checks if the value is the same as the output of `p()`. + // In such case, it copies the color components to the slot in `color_vars`. + // + // This solution is far from perfect, but it works in all the documented + // use-cases. + + const double num = color[0] << 24 | color[1] << 16 | color[2] << 8 | color[3]; + + state->last_fn_p_color.numeric = num; + for (int i = 0; i < FF_ARRAY_ELEMS(color); i++) + state->last_fn_p_color.components[i] = (uint8_t)color[i]; + + return num; } static int vgs_eval_state_init( @@ -1609,7 +1634,9 @@ static int vgs_eval_state_init( state->log_ctx = log_ctx; state->frame = frame; + state->rcp.status = RCP_NONE; + state->last_fn_p_color.numeric = NAN; if (program->proc_names != NULL) { state->procedures = av_calloc(sizeof(struct VGSProcedure), program->proc_names_count); @@ -2476,9 +2503,17 @@ static int vgs_eval( const int user_var = statement->args[0].constant; av_assert0(user_var >= VAR_U0 && user_var < (VAR_U0 + USER_VAR_COUNT)); - color_copy(&state->color_vars[user_var - VAR_U0], &colors[1]); state->vars[user_var] = numerics[1]; + // Take the color from `p()`, if any. + cairo_color *color = &state->color_vars[user_var - VAR_U0]; + if (state->last_fn_p_color.numeric == numerics[1]) { + for (int i = 0; i < FF_ARRAY_ELEMS(*color); i++) + (*color)[i] = state->last_fn_p_color.components[i] / 255.0; + } else { + color_copy(color, &colors[1]); + } + break; } diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index 0c6cbb2ee2..07b8632c6f 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -617,13 +617,14 @@ fate-filter-tiltandshift-410: CMD = framecrc -c:v pgmyuv -i $(SRC) -flags +bitex fate-filter-tiltandshift-422: CMD = framecrc -c:v pgmyuv -i $(SRC) -flags +bitexact -vf scale=sws_flags=+accurate_rnd+bitexact,format=yuv422p,tiltandshift fate-filter-tiltandshift-444: CMD = framecrc -c:v pgmyuv -i $(SRC) -flags +bitexact -vf scale=sws_flags=+accurate_rnd+bitexact,format=yuv444p,tiltandshift -DRAWVG_SCRIPT_LINES = tests/data/fate/drawvg.lines -$(DRAWVG_SCRIPT_LINES): $(SRC_PATH)/tests/ref/lavf/drawvg.lines +DRAWVG_SCRIPT_VIDEO = tests/data/fate/drawvg.video +$(DRAWVG_SCRIPT_VIDEO): TAG = COPY +$(DRAWVG_SCRIPT_VIDEO): $(SRC_PATH)/tests/ref/lavf/drawvg.video $(M)cp $< $@ FATE_FILTER_VSYNTH_VIDEO_FILTER-$(CONFIG_DRAWVG_FILTER) += fate-filter-drawvg-video -fate-filter-drawvg-video: $(DRAWVG_SCRIPT_LINES) -fate-filter-drawvg-video: CMD = video_filter scale,format=bgr0,drawvg=file=$(DRAWVG_SCRIPT_LINES) +fate-filter-drawvg-video: $(DRAWVG_SCRIPT_VIDEO) +fate-filter-drawvg-video: CMD = video_filter scale,format=bgr0,drawvg=file=$(DRAWVG_SCRIPT_VIDEO) tests/pixfmts.mak: TAG = GEN tests/pixfmts.mak: ffmpeg$(PROGSSUF)$(EXESUF) | tests diff --git a/tests/ref/fate/filter-drawvg-video b/tests/ref/fate/filter-drawvg-video index 0a646f6e2e..bd339be9b2 100644 --- a/tests/ref/fate/filter-drawvg-video +++ b/tests/ref/fate/filter-drawvg-video @@ -1 +1 @@ -drawvg-video caa7642950ab2fb1367bd28c287f31bd +drawvg-video 0f73962365b69779a604c5d41a4b7ae3 diff --git a/tests/ref/lavf/drawvg.lines b/tests/ref/lavf/drawvg.lines deleted file mode 100644 index e145052d50..0000000000 --- a/tests/ref/lavf/drawvg.lines +++ /dev/null @@ -1,10 +0,0 @@ -// Render a square, for `make fate-filter-drawvg-video`. - -M 10 10 -l 0 10 -h 10 -v -10 -h -10 -z -setcolor blue -stroke diff --git a/tests/ref/lavf/drawvg.video b/tests/ref/lavf/drawvg.video new file mode 100644 index 0000000000..89f6123385 --- /dev/null +++ b/tests/ref/lavf/drawvg.video @@ -0,0 +1,13 @@ +// Render a square, for `make fate-filter-drawvg-video`. + +setvar pixel (p(10, 10)) + +M 10 10 +l 0 100 +h 100 +v -100 +h -100 +z + +setcolor pixel +fill _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
