static void check_filter_status(int filter_id, hb_value_t *settings) { int disable = 0; if (settings == NULL) { return; } switch (filter_id) { case HB_FILTER_ROTATE: { int angle = hb_dict_get_int(settings, "angle"); int hflip = hb_dict_get_int(settings, "hflip"); disable = angle == 0 && hflip == 0; } break; case HB_FILTER_DEBLOCK: { int qp = hb_dict_get_int(settings, "qp"); disable = qp < 5; } break; default: { } break; } if (disable) { hb_dict_set(settings, "disable", hb_value_bool(disable)); } }
// Get json array of filter tune name and short_name char * hb_filter_get_tunes_json(int filter_id) { hb_value_array_t * array = hb_value_array_init(); int ii, count = 0; hb_filter_param_t * table; table = filter_param_get_tunes_internal(filter_id, NULL); for (count = 0; table[count].name != NULL; count++); for (ii = 0; ii < count; ii++) { hb_dict_t * dict = hb_dict_init(); hb_dict_set(dict, "short_name", hb_value_string(table[ii].short_name)); hb_dict_set(dict, "name", hb_value_string(table[ii].name)); hb_value_array_append(array, dict); } char * result = hb_value_get_json(array); hb_value_free(&array); return result; }
static hb_value_t * generate_deblock_settings(const char * preset, const char * custom) { hb_dict_t * settings = NULL; // Deblock "presets" are just the QP value. 0 disables. if ((preset == NULL || !strcasecmp(preset, "custom"))) { settings = hb_parse_filter_settings(custom); } else { settings = hb_dict_init(); int qp = strtol(preset, NULL, 0); hb_dict_set(settings, "qp", hb_value_int(qp)); } return settings; }
hb_dict_t * hb_encopts_to_dict( const char * encopts, int encoder ) { hb_dict_t * dict = NULL; if( encopts && *encopts ) { char *cur_opt, *opts_start, *value; const char *name; dict = hb_dict_init( 10 ); if( !dict ) return NULL; cur_opt = opts_start = strdup( encopts ); if( opts_start ) { while( *cur_opt ) { name = cur_opt; cur_opt += strcspn( cur_opt, ":" ); if( *cur_opt ) { *cur_opt = 0; cur_opt++; } value = strchr( name, '=' ); if( value ) { *value = 0; value++; } // x264 has multiple names for some options if( encoder == HB_VCODEC_X264 ) name = hb_x264_encopt_name( name ); hb_dict_set( &dict, name, value ); } } free( opts_start ); } return dict; }
/* NL-means presets and tunes * * Presets adjust strength: * ultralight - visually transparent * light * medium * strong * * Tunes adjust settings to the specified content type: * none * film - most content, live action * grain - like film but preserves luma grain * highmotion - like film but avoids color smearing with stronger settings * animation - cel animation such as cartoons, anime * tape - analog tape sources such as VHS * sprite - 1-/4-/8-/16-bit 2-dimensional games */ static hb_dict_t * generate_nlmeans_settings(const char *preset, const char *tune, const char *custom) { hb_dict_t * settings; if (preset == NULL) return NULL; if (preset == NULL || !strcasecmp(preset, "custom")) { return hb_parse_filter_settings(custom); } if (!strcasecmp(preset, "ultralight") || !strcasecmp(preset, "light") || !strcasecmp(preset, "medium") || !strcasecmp(preset, "strong")) { double strength[2], origin_tune[2]; int patch_size[2], range[2], frames[2], prefilter[2]; if (tune == NULL || !strcasecmp(tune, "none")) { strength[0] = strength[1] = 6; origin_tune[0] = origin_tune[1] = 1; patch_size[0] = patch_size[1] = 7; range[0] = range[1] = 3; frames[0] = frames[1] = 2; prefilter[0] = prefilter[1] = 0; if (!strcasecmp(preset, "ultralight")) { strength[0] = strength[1] = 1.5; } else if (!strcasecmp(preset, "light")) { strength[0] = strength[1] = 3; } else if (!strcasecmp(preset, "strong")) { strength[0] = strength[1] = 10; } } else if (!strcasecmp(tune, "film")) { strength[0] = 6; strength[1] = 8; origin_tune[0] = origin_tune[1] = 0.8; patch_size[0] = patch_size[1] = 7; range[0] = range[1] = 3; frames[0] = frames[1] = 2; prefilter[0] = prefilter[1] = 0; if (!strcasecmp(preset, "ultralight")) { strength[0] = 1.5; strength[1] = 2.4; origin_tune[0] = 0.9; origin_tune[1] = 0.9; } else if (!strcasecmp(preset, "light")) { strength[0] = 3; strength[1] = 4; origin_tune[0] = 0.9; origin_tune[1] = 0.9; } else if (!strcasecmp(preset, "strong")) { strength[0] = 8; strength[1] = 10; origin_tune[0] = 0.6; origin_tune[1] = 0.6; } } else if (!strcasecmp(tune, "grain")) { strength[0] = 0; strength[1] = 6; origin_tune[0] = origin_tune[1] = 0.8; patch_size[0] = patch_size[1] = 7; range[0] = range[1] = 3; frames[0] = frames[1] = 2; prefilter[0] = prefilter[1] = 0; if (!strcasecmp(preset, "ultralight")) { strength[0] = 0; strength[1] = 2.4; origin_tune[0] = 0.9; origin_tune[1] = 0.9; } else if (!strcasecmp(preset, "light")) { strength[0] = 0; strength[1] = 3.5; origin_tune[0] = 0.9; origin_tune[1] = 0.9; } else if (!strcasecmp(preset, "strong")) { strength[0] = 0; strength[1] = 8; origin_tune[0] = 0.6; origin_tune[1] = 0.6; } } else if (!strcasecmp(tune, "highmotion")) { strength[0] = 6; strength[1] = 6; origin_tune[0] = 0.8; origin_tune[1] = 0.7; patch_size[0] = 7; patch_size[1] = 7; range[0] = 3; range[1] = 5; frames[0] = 2; frames[1] = 1; prefilter[0] = 0; prefilter[1] = 0; if (!strcasecmp(preset, "ultralight")) { strength[0] = 1.5; strength[1] = 2.4; origin_tune[0] = 0.9; origin_tune[1] = 0.9; } else if (!strcasecmp(preset, "light")) { strength[0] = 3; strength[1] = 3.25; origin_tune[0] = 0.9; origin_tune[1] = 0.8; } else if (!strcasecmp(preset, "strong")) { strength[0] = 8; strength[1] = 6.75; origin_tune[0] = 0.6; origin_tune[1] = 0.5; } } else if (!strcasecmp(tune, "animation")) { strength[0] = 5; strength[1] = 4; origin_tune[0] = origin_tune[1] = 0.15; patch_size[0] = patch_size[1] = 5; range[0] = range[1] = 7; frames[0] = frames[1] = 4; prefilter[0] = prefilter[1] = 0; if (!strcasecmp(preset, "ultralight")) { strength[0] = 2.5; strength[1] = 2; frames[0] = 2; frames[1] = 2; } else if (!strcasecmp(preset, "light")) { strength[0] = 3; strength[1] = 2.25; frames[0] = 3; frames[1] = 3; } else if (!strcasecmp(preset, "strong")) { strength[0] = 10; strength[1] = 8; } } else if (!strcasecmp(tune, "tape")) { strength[0] = 3; strength[1] = 6; origin_tune[0] = 0.8; origin_tune[1] = 0.8; patch_size[0] = 3; patch_size[1] = 5; range[0] = 5; range[1] = 5; frames[0] = 2; frames[1] = 2; prefilter[0] = 0; prefilter[1] = 0; if (!strcasecmp(preset, "ultralight")) { strength[0] = 1.5; strength[1] = 5; origin_tune[0] = 0.9; origin_tune[1] = 0.9; frames[0] = 1; frames[1] = 1; } else if (!strcasecmp(preset, "light")) { strength[0] = 2; strength[1] = 6; origin_tune[0] = 0.9; origin_tune[1] = 0.9; } else if (!strcasecmp(preset, "strong")) { strength[0] = 3.5; strength[1] = 8; origin_tune[0] = 0.6; origin_tune[1] = 0.6; patch_size[0] = 5; patch_size[1] = 5; } } else if (!strcasecmp(tune, "sprite")) { strength[0] = 3; strength[1] = 4; origin_tune[0] = 0.15; origin_tune[1] = 0.5; patch_size[0] = 5; patch_size[1] = 5; range[0] = 5; range[1] = 9; frames[0] = 2; frames[1] = 4; prefilter[0] = 0; prefilter[1] = 0; if (!strcasecmp(preset, "ultralight")) { strength[0] = 1.5; strength[1] = 3; range[0] = 5; range[1] = 7; frames[0] = 1; frames[1] = 2; } else if (!strcasecmp(preset, "light")) { strength[0] = 2; strength[1] = 4; frames[0] = 2; frames[1] = 2; } else if (!strcasecmp(preset, "strong")) { strength[0] = 3; strength[1] = 4; range[0] = 7; range[1] = 11; } } else { fprintf(stderr, "Unrecognized nlmeans tune (%s).\n", tune); return NULL; } settings = hb_dict_init(); hb_dict_set(settings, "y-strength", hb_value_double(strength[0])); hb_dict_set(settings, "y-origin-tune", hb_value_double(origin_tune[0])); hb_dict_set(settings, "y-patch-size", hb_value_int(patch_size[0])); hb_dict_set(settings, "y-range", hb_value_int(range[0])); hb_dict_set(settings, "y-frame-count", hb_value_int(frames[0])); hb_dict_set(settings, "y-prefilter", hb_value_int(prefilter[0])); hb_dict_set(settings, "cb-strength", hb_value_double(strength[1])); hb_dict_set(settings, "cb-origin-tune", hb_value_double(origin_tune[1])); hb_dict_set(settings, "cb-patch-size", hb_value_int(patch_size[1])); hb_dict_set(settings, "cb-range", hb_value_int(range[1])); hb_dict_set(settings, "cb-frame-count", hb_value_int(frames[1])); hb_dict_set(settings, "cb-prefilter", hb_value_int(prefilter[1])); } else { settings = hb_parse_filter_settings(preset); if (tune != NULL) { fprintf(stderr, "Custom nlmeans parameters specified; ignoring nlmeans tune (%s).\n", tune); } } return settings; }
static void end_element( void *ud, const xmlChar *xname) { char *name = (char*)xname; parse_data_t *pd = (parse_data_t*)ud; int id; union { int id; void * pid; } start_id; int ii; // Check to see if the first element found has been closed // If so, ignore any junk following it. if (pd->closed_top) return; for (ii = 0; ii < TAG_MAP_SZ; ii++) { if (strcmp(name, tag_map[ii].tag) == 0) { id = tag_map[ii].id; break; } } if (ii == TAG_MAP_SZ) { hb_error("Unrecognized start tag (%s)", name); return; } start_id.pid = queue_pop_head(pd->tag_stack); if (start_id.id != id) hb_error("start tag != end tag: (%s %d) %d", name, id, id); hb_value_t *gval = NULL; hb_value_t *current = queue_peek_head(pd->stack); hb_value_type_t gtype = 0; const char *value; if (pd->value != NULL) value = pd->value; else value = ""; switch (id) { case P_PLIST: { // Ignore } break; case P_KEY: { if (pd->key) free(pd->key); pd->key = strdup(value); return; } break; case P_DICT: { queue_pop_head(pd->stack); } break; case P_ARRAY: { queue_pop_head(pd->stack); } break; case P_INTEGER: { uint64_t val = strtoll(value, NULL, 0); gval = hb_value_int(val); } break; case P_REAL: { double val = strtod(value, NULL); gval = hb_value_double(val); } break; case P_STRING: { gval = hb_value_string(value); } break; case P_TRUE: { gval = hb_value_bool(1); } break; case P_FALSE: { gval = hb_value_bool(0); } break; default: { hb_error("Unhandled plist type %d", id); } break; } if (gval) { // Get the top of the data structure stack and if it's an array // or dict, add the current element if (current == NULL) { pd->plist = gval; pd->closed_top = 1; return; } gtype = hb_value_type(current); if (gtype == HB_VALUE_TYPE_ARRAY) { hb_value_array_append(current, gval); } else if (gtype == HB_VALUE_TYPE_DICT) { if (pd->key == NULL) { hb_error("No key for dictionary item"); hb_value_free(&gval); } else { hb_dict_set(current, pd->key, gval); } } else { hb_error("Invalid container type. This shouldn't happen"); } } if (queue_is_empty(pd->stack)) pd->closed_top = 1; }
static void start_element( void *ud, const xmlChar *xname, const xmlChar **attr_names) { char *name = (char*)xname; parse_data_t *pd = (parse_data_t*)ud; union { int id; void * pid; } id; int ii; // Check to see if the first element found has been closed // If so, ignore any junk following it. if (pd->closed_top) return; for (ii = 0; ii < TAG_MAP_SZ; ii++) { if (strcmp(name, tag_map[ii].tag) == 0) { id.id = tag_map[ii].id; break; } } if (ii == TAG_MAP_SZ) { hb_error("Unrecognized start tag (%s)", name); return; } if (pd->value) { free(pd->value); pd->value = NULL; } queue_push_head(pd->tag_stack, id.pid); hb_value_type_t gtype = 0; hb_value_t *gval = NULL; hb_value_t *current = queue_peek_head(pd->stack); switch (id.id) { case P_PLIST: { // Ignore } break; case P_KEY: { if (pd->key) free(pd->key); pd->key = NULL; } break; case P_DICT: { gval = hb_dict_init(); queue_push_head(pd->stack, gval); } break; case P_ARRAY: { gval = hb_value_array_init(); queue_push_head(pd->stack, gval); } break; case P_INTEGER: { } break; case P_REAL: { } break; case P_STRING: { } break; case P_DATE: { } break; case P_TRUE: { } break; case P_FALSE: { } break; case P_DATA: { } break; } // Add the element to the current container if (gval) { // There's an element to add if (current == NULL) { pd->plist = gval; return; } gtype = hb_value_type(current); if (gtype == HB_VALUE_TYPE_ARRAY) { hb_value_array_append(current, gval); } else if (gtype == HB_VALUE_TYPE_DICT) { if (pd->key == NULL) { hb_error("No key for dictionary item"); hb_value_free(&gval); } else { hb_dict_set(current, pd->key, gval); } } else { hb_error("Invalid container type. This shouldn't happen"); } } }