diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c index 9f632405ce..c62cba8101 100644 --- a/libavfilter/vf_hue.c +++ b/libavfilter/vf_hue.c @@ -100,23 +100,32 @@ static inline void compute_sin_and_cos(HueContext *hue) hue->hue_cos = rint(cos(hue->hue) * (1 << 16) * hue->saturation); } -static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx) +static int set_expr(AVExpr **pexpr_ptr, char **expr_ptr, + const char *expr, const char *option, void *log_ctx) { int ret; - AVExpr *old = NULL; + AVExpr *new_pexpr; + char *new_expr; - if (*pexpr) - old = *pexpr; - ret = av_expr_parse(pexpr, expr, var_names, + new_expr = av_strdup(expr); + if (!new_expr) + return AVERROR(ENOMEM); + ret = av_expr_parse(&new_pexpr, expr, var_names, NULL, NULL, NULL, NULL, 0, log_ctx); if (ret < 0) { av_log(log_ctx, AV_LOG_ERROR, "Error when evaluating the expression '%s' for %s\n", expr, option); - *pexpr = old; + av_free(new_expr); return ret; } - av_expr_free(old); + + if (*pexpr_ptr) + av_expr_free(*pexpr_ptr); + *pexpr_ptr = new_pexpr; + av_freep(expr_ptr); + *expr_ptr = new_expr; + return 0; } @@ -134,13 +143,15 @@ static av_cold int init(AVFilterContext *ctx) #define SET_EXPR(expr, option) \ if (hue->expr##_expr) do { \ - ret = set_expr(&hue->expr##_pexpr, hue->expr##_expr, option, ctx); \ + ret = set_expr(&hue->expr##_pexpr, &hue->expr##_expr, \ + hue->expr##_expr, option, ctx); \ if (ret < 0) \ return ret; \ } while (0) SET_EXPR(saturation, "s"); SET_EXPR(hue_deg, "h"); SET_EXPR(hue, "H"); +#undef SET_EXPR av_log(ctx, AV_LOG_VERBOSE, "H_expr:%s h_deg_expr:%s s_expr:%s\n", @@ -306,16 +317,28 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar char *res, int res_len, int flags) { HueContext *hue = ctx->priv; + int ret; -#define SET_CMD(expr, option) do { \ - if (!strcmp(cmd, option)) \ - return set_expr(&hue->expr##_pexpr, args, cmd, ctx); \ -} while (0) - SET_CMD(hue_deg, "h"); - SET_CMD(hue, "H"); - SET_CMD(saturation, "s"); +#define SET_EXPR(expr, option) \ + do { \ + ret = set_expr(&hue->expr##_pexpr, &hue->expr##_expr, \ + args, option, ctx); \ + if (ret < 0) \ + return ret; \ + } while (0) - return AVERROR(ENOSYS); + if (!strcmp(cmd, "h")) { + SET_EXPR(hue_deg, "h"); + av_freep(&hue->hue_expr); + } else if (!strcmp(cmd, "H")) { + SET_EXPR(hue, "H"); + av_freep(&hue->hue_deg_expr); + } else if (!strcmp(cmd, "s")) { + SET_EXPR(saturation, "s"); + } else + return AVERROR(ENOSYS); + + return 0; } static const AVFilterPad hue_inputs[] = {