| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -36,12 +36,6 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "internal.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "video.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define HUE_DEFAULT_VAL 0 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SAT_DEFAULT_VAL 1 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define HUE_DEFAULT_VAL_STRING AV_STRINGIFY(HUE_DEFAULT_VAL) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SAT_DEFAULT_VAL_STRING AV_STRINGIFY(SAT_DEFAULT_VAL) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SAT_MIN_VAL -10 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SAT_MAX_VAL 10 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -78,7 +72,6 @@ typedef struct { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int      vsub; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int32_t hue_sin; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int32_t hue_cos; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int      flat_syntax; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    double   var_values[VAR_NB]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} HueContext; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -87,9 +80,9 @@ typedef struct { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static const AVOption hue_options[] = { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    { "h", "set the hue angle degrees expression", OFFSET(hue_deg_expr), AV_OPT_TYPE_STRING, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      { .str = NULL }, .flags = FLAGS }, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    { "H", "set the hue angle radians expression", OFFSET(hue_expr), AV_OPT_TYPE_STRING, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      { .str = NULL }, .flags = FLAGS }, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    { "s", "set the saturation expression", OFFSET(saturation_expr), AV_OPT_TYPE_STRING, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      { .str = "1" }, .flags = FLAGS }, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    { "H", "set the hue angle radians expression", OFFSET(hue_expr), AV_OPT_TYPE_STRING, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      { .str = NULL }, .flags = FLAGS }, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    { NULL } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			}; | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -107,99 +100,62 @@ static inline void compute_sin_and_cos(HueContext *hue) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->hue_cos = rint(cos(hue->hue) * (1 << 16) * hue->saturation); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SET_EXPRESSION(attr, name) do {                                           \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (hue->attr##_expr) {                                                       \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if ((ret = av_expr_parse(&hue->attr##_pexpr, hue->attr##_expr, var_names, \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                                 NULL, NULL, NULL, NULL, 0, ctx)) < 0) {          \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            av_log(ctx, AV_LOG_ERROR,                                             \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                   "Parsing failed for expression " #name "='%s'",                \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                   hue->attr##_expr);                                             \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            hue->attr##_expr  = old_##attr##_expr;                                \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            hue->attr##_pexpr = old_##attr##_pexpr;                               \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return AVERROR(EINVAL);                                               \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } else if (old_##attr##_pexpr) {                                          \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            av_freep(&old_##attr##_expr);                                         \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            av_expr_free(old_##attr##_pexpr);                                     \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            old_##attr##_pexpr = NULL;                                            \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        }                                                                         \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } else {                                                                      \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        hue->attr##_expr = old_##attr##_expr;                                     \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    }                                                                             \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} while (0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static inline int set_options(AVFilterContext *ctx, const char *args) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    HueContext *hue = ctx->priv; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int ret; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    char   *old_hue_expr,  *old_hue_deg_expr,  *old_saturation_expr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    AVExpr *old_hue_pexpr, *old_hue_deg_pexpr, *old_saturation_pexpr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    static const char *shorthand[] = { "h", "s", NULL }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    old_hue_expr        = hue->hue_expr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    old_hue_deg_expr    = hue->hue_deg_expr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    old_saturation_expr = hue->saturation_expr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    old_hue_pexpr        = hue->hue_pexpr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    old_hue_deg_pexpr    = hue->hue_deg_pexpr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    old_saturation_pexpr = hue->saturation_pexpr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->hue_expr     = NULL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->hue_deg_expr = NULL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->saturation_expr = NULL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if ((ret = av_opt_set_from_string(hue, args, shorthand, "=", ":")) < 0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    AVExpr *old = NULL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (*pexpr) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        old = *pexpr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    ret = av_expr_parse(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; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return ret; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    av_expr_free(old); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static av_cold int init(AVFilterContext *ctx, const char *args) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    HueContext *hue = ctx->priv; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int ret; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (hue->hue_expr && hue->hue_deg_expr) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        av_log(ctx, AV_LOG_ERROR, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			               "H and h options are incompatible and cannot be specified " | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			               "at the same time\n"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        hue->hue_expr     = old_hue_expr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        hue->hue_deg_expr = old_hue_deg_expr; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return AVERROR(EINVAL); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    SET_EXPRESSION(hue_deg, h); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    SET_EXPRESSION(hue, H); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    SET_EXPRESSION(saturation, s); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->flat_syntax = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SET_EXPR(expr, option)                                          \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (hue->expr##_expr) do {                                          \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        ret = set_expr(&hue->expr##_pexpr, 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"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    av_log(ctx, AV_LOG_VERBOSE, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           "H_expr:%s h_deg_expr:%s s_expr:%s\n", | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           hue->hue_expr, hue->hue_deg_expr, hue->saturation_expr); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    compute_sin_and_cos(hue); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static av_cold int init(AVFilterContext *ctx, const char *args) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    HueContext *hue = ctx->priv; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->class = &hue_class; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    av_opt_set_defaults(hue); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->saturation    = SAT_DEFAULT_VAL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->hue           = HUE_DEFAULT_VAL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->hue_deg_pexpr = NULL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->hue_pexpr     = NULL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->flat_syntax   = 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return set_options(ctx, args); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static av_cold void uninit(AVFilterContext *ctx) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    HueContext *hue = ctx->priv; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    av_opt_free(hue); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    av_free(hue->hue_deg_expr); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    av_expr_free(hue->hue_deg_pexpr); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    av_free(hue->hue_expr); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    av_expr_free(hue->hue_pexpr); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    av_free(hue->saturation_expr); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    av_expr_free(hue->saturation_pexpr); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -295,7 +251,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        av_frame_copy_props(outpic, inpic); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (!hue->flat_syntax) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* todo: reindent */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        hue->var_values[VAR_T]   = TS2T(inpic->pts, inlink->time_base); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        hue->var_values[VAR_PTS] = TS2D(inpic->pts); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -323,7 +279,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			               hue->var_values[VAR_T], (int)hue->var_values[VAR_N]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        compute_sin_and_cos(hue); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    hue->var_values[VAR_N] += 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -345,10 +300,17 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                           char *res, int res_len, int flags) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (!strcmp(cmd, "reinit")) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return set_options(ctx, args); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return AVERROR(ENOSYS); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    HueContext *hue = ctx->priv; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define SET_CMD(expr, option)                                          \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (!strcmp(cmd, option)) do {                                     \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return set_expr(&hue->expr##_pexpr, args, cmd, ctx);       \ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } while (0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    SET_CMD(hue_deg,    "h"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    SET_CMD(hue,        "H"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    SET_CMD(saturation, "s"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return AVERROR(ENOSYS); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static const AVFilterPad hue_inputs[] = { | 
		
		
	
	
		
			
				| 
				
					
				
				
				
				 | 
			
			 | 
			
  |