1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
6 * x264handler.c is free software.
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
18 #include "callbacks.h"
20 #include "hb-backend.h"
21 #include "x264handler.h"
23 gint ghb_lookup_bframes(const gchar *options);
24 static void x264_opt_update(signal_user_data_t *ud, GtkWidget *widget);
25 static gchar* sanitize_x264opts(signal_user_data_t *ud, const gchar *options);
27 // Flag needed to prevent x264 options processing from chasing its tail
28 static gboolean ignore_options_update = FALSE;
31 x264_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
33 ghb_widget_to_setting(ud->settings, widget);
34 if (!ignore_options_update)
36 ignore_options_update = TRUE;
37 x264_opt_update(ud, widget);
38 ignore_options_update = FALSE;
40 ghb_check_dependency(ud, widget, NULL);
41 ghb_clear_presets_selection(ud);
45 x264_slider_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
47 ghb_widget_to_setting(ud->settings, widget);
49 // Lock slider values to multiples of step_increment
50 GtkAdjustment * adj = gtk_range_get_adjustment(GTK_RANGE(widget));
51 gdouble step = gtk_adjustment_get_step_increment(adj);
52 gdouble val = gtk_range_get_value(GTK_RANGE(widget));
53 gdouble new_val = ((int)((val + step / 2) / step)) * step;
54 gdouble diff = val - new_val;
55 if ( diff > 0.0001 || diff < -0.0001 )
57 gtk_range_set_value(GTK_RANGE(widget), new_val);
59 else if (!ignore_options_update)
61 ignore_options_update = TRUE;
62 x264_opt_update(ud, widget);
63 ignore_options_update = FALSE;
65 ghb_check_dependency(ud, widget, NULL);
66 ghb_clear_presets_selection(ud);
69 G_MODULE_EXPORT gchar*
70 x264_format_slider_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
72 return g_strdup_printf("%-6.6g", val);
77 x264_me_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
81 ghb_widget_to_setting(ud->settings, widget);
82 if (!ignore_options_update)
84 ignore_options_update = TRUE;
85 x264_opt_update(ud, widget);
86 ignore_options_update = FALSE;
88 ghb_check_dependency(ud, widget, NULL);
89 ghb_clear_presets_selection(ud);
90 widget = GHB_WIDGET(ud->builder, "x264_merange");
91 me = ghb_settings_combo_int(ud->settings, "x264_me");
95 gtk_spin_button_set_range(GTK_SPIN_BUTTON(widget), 4, 16);
100 gtk_spin_button_set_range(GTK_SPIN_BUTTON(widget), 4, 64);
105 x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
107 g_debug("x264_entry_changed_cb ()");
108 if (!ignore_options_update)
113 textview = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264Option"));
114 ghb_widget_to_setting(ud->settings, textview);
115 options = ghb_settings_get_string(ud->settings, "x264Option");
116 ignore_options_update = TRUE;
117 ghb_x264_parse_options(ud, options);
118 if (!GTK_WIDGET_HAS_FOCUS(textview))
122 sopts = sanitize_x264opts(ud, options);
123 ghb_ui_update(ud, "x264Option", ghb_string_value(sopts));
124 ghb_x264_parse_options(ud, sopts);
128 ignore_options_update = FALSE;
132 G_MODULE_EXPORT gboolean
133 x264_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
134 signal_user_data_t *ud)
136 gchar *options, *sopts;
138 ghb_widget_to_setting(ud->settings, widget);
139 options = ghb_settings_get_string(ud->settings, "x264Option");
140 sopts = sanitize_x264opts(ud, options);
141 ignore_options_update = TRUE;
142 if (sopts != NULL && strcmp(sopts, options) != 0)
144 ghb_ui_update(ud, "x264Option", ghb_string_value(sopts));
145 ghb_x264_parse_options(ud, sopts);
149 ignore_options_update = FALSE;
182 trans_x264_val(trans_table_t *trans, char *val)
188 for (ii = 0; ii < trans->count; ii++)
190 if (strcmp(val, trans->map[ii].x264_val) == 0)
192 return trans->map[ii].ui_val;
199 trans_ui_val(trans_table_t *trans, char *val)
205 for (ii = 0; ii < trans->count; ii++)
207 if (strcmp(val, trans->map[ii].ui_val) == 0)
209 return trans->map[ii].x264_val;
215 struct x264_opt_map_s
221 trans_table_t *translation;
225 static gchar *x264_ref_syns[] = {"ref", "frameref", NULL};
226 static gchar *x264_bframes_syns[] = {"bframes", NULL};
227 static gchar *x264_badapt_syns[] = {"b-adapt", "b_adapt", NULL};
228 static gchar *x264_direct_syns[] =
229 {"direct", "direct-pred", "direct_pred", NULL};
230 static gchar *x264_weightp_syns[] = {"weightp", NULL};
231 static gchar *x264_bpyramid_syns[] = {"b-pyramid", "b_pyramid", NULL};
232 static gchar *x264_me_syns[] = {"me", NULL};
233 static gchar *x264_merange_syns[] = {"merange", "me-range", "me_range", NULL};
234 static gchar *x264_subme_syns[] = {"subme", "subq", NULL};
235 static gchar *x264_aqmode_syns[] = {"aq-mode", NULL};
236 static gchar *x264_analyse_syns[] = {"partitions", "analyse", NULL};
237 static gchar *x264_8x8dct_syns[] = {"8x8dct", NULL};
238 static gchar *x264_deblock_syns[] = {"deblock", "filter", NULL};
239 static gchar *x264_trellis_syns[] = {"trellis", NULL};
240 static gchar *x264_pskip_syns[] = {"no-fast-pskip", "no_fast_pskip", NULL};
241 static gchar *x264_psy_syns[] = {"psy-rd", "psy_rd", NULL};
242 static gchar *x264_aq_strength_syns[] = {"aq-strength", "aq_strength", NULL};
243 static gchar *x264_mbtree_syns[] = {"mbtree", NULL};
244 static gchar *x264_decimate_syns[] =
245 {"no-dct-decimate", "no_dct_decimate", NULL};
246 static gchar *x264_cabac_syns[] = {"cabac", NULL};
249 find_syn_match(const gchar *opt, gchar **syns)
252 for (ii = 0; syns[ii] != NULL; ii++)
254 if (strcmp(opt, syns[ii]) == 0)
260 struct x264_opt_map_s x264_opt_map[] =
262 {x264_ref_syns, "x264_refs", "3", X264_OPT_INT},
263 {x264_bframes_syns, "x264_bframes", "3", X264_OPT_INT},
264 {x264_direct_syns, "x264_direct", "spatial", X264_OPT_COMBO},
265 {x264_badapt_syns, "x264_b_adapt", "1", X264_OPT_COMBO},
266 {x264_weightp_syns, "x264_weighted_pframes", "2", X264_OPT_COMBO},
267 {x264_bpyramid_syns, "x264_bpyramid", "normal", X264_OPT_COMBO},
268 {x264_me_syns, "x264_me", "hex", X264_OPT_COMBO},
269 {x264_merange_syns, "x264_merange", "16", X264_OPT_INT},
270 {x264_subme_syns, "x264_subme", "7", X264_OPT_COMBO},
271 {x264_aqmode_syns, "x264_aqmode", "1", X264_OPT_INT_NONE},
272 {x264_analyse_syns, "x264_analyse", "p8x8,b8x8,i8x8,i4x4", X264_OPT_COMBO},
273 {x264_8x8dct_syns, "x264_8x8dct", "1", X264_OPT_BOOL},
274 {x264_deblock_syns, "x264_deblock_alpha", "0,0", X264_OPT_DEBLOCK},
275 {x264_deblock_syns, "x264_deblock_beta", "0,0", X264_OPT_DEBLOCK},
276 {x264_trellis_syns, "x264_trellis", "1", X264_OPT_COMBO},
277 {x264_pskip_syns, "x264_no_fast_pskip", "0", X264_OPT_BOOL},
278 {x264_decimate_syns, "x264_no_dct_decimate", "0", X264_OPT_BOOL},
279 {x264_cabac_syns, "x264_cabac", "1", X264_OPT_BOOL},
280 {x264_aq_strength_syns, "x264_aq_strength", "1", X264_OPT_DOUBLE},
281 {x264_psy_syns, "x264_psy_rd", "1,0", X264_OPT_PSY},
282 {x264_psy_syns, "x264_psy_trell", "1,0", X264_OPT_PSY},
283 {x264_mbtree_syns, "x264_mbtree", "1", X264_OPT_BOOL_NONE},
285 #define X264_OPT_MAP_SIZE (sizeof(x264_opt_map)/sizeof(struct x264_opt_map_s))
288 x264_opt_get_default(const gchar *opt)
291 for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
293 if (find_syn_match(opt, x264_opt_map[jj].opt_syns) >= 0)
295 return x264_opt_map[jj].def_val;
302 x264_update_double(signal_user_data_t *ud, const gchar *name, const gchar *val)
306 if (val == NULL) return;
307 dval = g_strtod (val, NULL);
308 ghb_ui_update(ud, name, ghb_double_value(dval));
312 x264_update_int(signal_user_data_t *ud, const gchar *name, const gchar *val)
316 if (val == NULL) return;
317 ival = g_strtod (val, NULL);
318 ghb_ui_update(ud, name, ghb_int64_value(ival));
322 x264_update_int_setting(signal_user_data_t *ud, const gchar *name, const gchar *val)
326 if (val == NULL) return;
327 ival = g_strtod (val, NULL);
328 ghb_settings_set_value(ud->settings, name, ghb_int64_value(ival));
329 ghb_check_dependency(ud, NULL, name);
332 static gchar *true_str[] =
341 str_is_true(const gchar *str)
344 for (ii = 0; true_str[ii]; ii++)
346 if (g_ascii_strcasecmp(str, true_str[ii]) == 0)
353 x264_update_bool(signal_user_data_t *ud, const gchar *name, const gchar *val)
356 ghb_ui_update(ud, name, ghb_boolean_value(1));
358 ghb_ui_update(ud, name, ghb_boolean_value(str_is_true(val)));
362 x264_update_bool_setting(signal_user_data_t *ud, const gchar *name, const gchar *val)
365 ghb_settings_set_value(ud->settings, name, ghb_boolean_value(1));
367 ghb_settings_set_value(ud->settings, name, ghb_boolean_value(str_is_true(val)));
369 ghb_check_dependency(ud, NULL, name);
373 x264_update_combo(signal_user_data_t *ud, const gchar *name, const gchar *val)
379 gboolean foundit = FALSE;
382 if (val == NULL) return;
383 widget = GHB_WIDGET(ud->builder, name);
386 g_debug("Failed to find widget for key: %s\n", name);
389 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
390 if (gtk_tree_model_get_iter_first (store, &iter))
394 gtk_tree_model_get(store, &iter, 2, &shortOpt, 3, &ivalue, -1);
395 if (strcmp(shortOpt, val) == 0)
397 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
403 } while (gtk_tree_model_iter_next (store, &iter));
407 if (gtk_tree_model_get_iter_first (store, &iter))
411 gtk_tree_model_get(store, &iter, 2, &shortOpt, 3, &ivalue, -1);
412 if (strcmp(shortOpt, "custom") == 0)
414 gtk_list_store_set(GTK_LIST_STORE(store), &iter, 4, val, -1);
415 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
421 } while (gtk_tree_model_iter_next (store, &iter));
424 // Its possible the value hasn't changed. Since settings are only
425 // updated when the value changes, I'm initializing settings here as well.
426 ghb_widget_to_setting(ud->settings, widget);
430 x264_update_deblock(signal_user_data_t *ud, const gchar *xval)
432 gdouble avalue, bvalue;
437 if (xval == NULL) return;
438 val = g_strdup(xval);
442 gchar *pos = strchr(val, ',');
448 avalue = g_strtod (val, &end);
451 bvalue = g_strtod (bval, &end);
455 ghb_ui_update(ud, "x264_deblock_alpha", ghb_int64_value(avalue));
456 ghb_ui_update(ud, "x264_deblock_beta", ghb_int64_value(bvalue));
460 x264_parse_psy(const gchar *psy, gdouble *psy_rd, gdouble *psy_trell)
463 gchar *trell_val = NULL;
468 if (psy == NULL) return;
470 gchar *pos = strchr(val, ',');
476 *psy_rd = g_strtod (val, &end);
477 if (trell_val != NULL)
479 *psy_trell = g_strtod (trell_val, &end);
485 x264_update_psy(signal_user_data_t *ud, const gchar *xval)
487 gdouble rd_value, trell_value;
489 if (xval == NULL) return;
490 x264_parse_psy(xval, &rd_value, &trell_value);
491 ghb_ui_update(ud, "x264_psy_rd", ghb_double_value(rd_value));
492 ghb_ui_update(ud, "x264_psy_trell", ghb_double_value(trell_value));
495 static void do_update(signal_user_data_t *ud, char *name, gint type, char *val)
500 x264_update_int(ud, name, val);
502 case X264_OPT_DOUBLE:
503 x264_update_double(ud, name, val);
506 x264_update_bool(ud, name, val);
509 x264_update_combo(ud, name, val);
511 case X264_OPT_BOOL_NONE:
512 x264_update_bool_setting(ud, name, val);
514 case X264_OPT_INT_NONE:
515 x264_update_int_setting(ud, name, val);
521 ghb_x264_parse_options(signal_user_data_t *ud, const gchar *options)
523 gchar **split = g_strsplit(options, ":", -1);
524 if (split == NULL) return;
529 for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
530 x264_opt_map[jj].found = FALSE;
532 for (ii = 0; split[ii] != NULL; ii++)
535 gchar *pos = strchr(split[ii], '=');
541 for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
543 if (find_syn_match(split[ii], x264_opt_map[jj].opt_syns) >= 0)
545 x264_opt_map[jj].found = TRUE;
546 switch(x264_opt_map[jj].type)
549 x264_update_int(ud, x264_opt_map[jj].name, val);
551 case X264_OPT_DOUBLE:
552 x264_update_double(ud, x264_opt_map[jj].name, val);
555 x264_update_bool(ud, x264_opt_map[jj].name, val);
558 x264_update_combo(ud, x264_opt_map[jj].name, val);
560 case X264_OPT_DEBLOCK:
561 // dirty little hack. mark deblock_beta found as well
562 x264_opt_map[jj+1].found = TRUE;
563 x264_update_deblock(ud, val);
566 // dirty little hack. mark psy_trell found as well
567 x264_opt_map[jj+1].found = TRUE;
568 x264_update_psy(ud, val);
570 case X264_OPT_BOOL_NONE:
571 x264_update_bool_setting(ud, x264_opt_map[jj].name, val);
573 case X264_OPT_INT_NONE:
574 x264_update_int_setting(ud, x264_opt_map[jj].name, val);
577 if (x264_opt_map[jj].translation == NULL)
579 val = trans_x264_val(x264_opt_map[jj].translation, val);
582 do_update(ud, x264_opt_map[jj].name,
583 x264_opt_map[jj].translation->ui_type, val);
584 // TODO un-grey the ui control
588 // TODO grey out the ui control
596 // For any options not found in the option string, set ui to
598 for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
600 if (!x264_opt_map[jj].found)
602 gchar *val = strdup(x264_opt_map[jj].def_val);
603 switch(x264_opt_map[jj].type)
606 x264_update_int(ud, x264_opt_map[jj].name, val);
608 case X264_OPT_DOUBLE:
609 x264_update_double(ud, x264_opt_map[jj].name, val);
612 x264_update_bool(ud, x264_opt_map[jj].name, val);
615 x264_update_combo(ud, x264_opt_map[jj].name, val);
617 case X264_OPT_DEBLOCK:
618 x264_update_deblock(ud, val);
621 x264_update_psy(ud, val);
623 case X264_OPT_BOOL_NONE:
624 x264_update_bool_setting(ud, x264_opt_map[jj].name, val);
626 case X264_OPT_INT_NONE:
627 x264_update_int_setting(ud, x264_opt_map[jj].name, val);
630 if (x264_opt_map[jj].translation == NULL)
632 val = g_strdup(trans_x264_val(x264_opt_map[jj].translation, val));
635 do_update(ud, x264_opt_map[jj].name,
636 x264_opt_map[jj].translation->ui_type, val);
637 // TODO un-grey the ui control
641 // TODO grey out the ui control
645 x264_opt_map[jj].found = TRUE;
653 get_deblock_val(signal_user_data_t *ud)
657 alpha = ghb_settings_get_string(ud->settings, "x264_deblock_alpha");
658 beta = ghb_settings_get_string(ud->settings, "x264_deblock_beta");
659 result = g_strdup_printf("%s,%s", alpha, beta);
666 get_psy_val(signal_user_data_t *ud)
669 gchar rd_str[8], trell_str[8];
671 rd = ghb_settings_get_double(ud->settings, "x264_psy_rd");
672 trell = ghb_settings_get_double(ud->settings, "x264_psy_trell");
673 g_ascii_formatd(rd_str, 8, "%g", rd);
674 g_ascii_formatd(trell_str, 8, "%g", trell);
675 result = g_strdup_printf("%s,%s", rd_str, trell_str);
680 x264_opt_update(signal_user_data_t *ud, GtkWidget *widget)
683 const gchar *name = ghb_get_setting_key(widget);
684 gchar **opt_syns = NULL;
685 const gchar *def_val = NULL;
687 trans_table_t *trans;
689 for (jj = 0; jj < X264_OPT_MAP_SIZE; jj++)
691 if (strcmp(name, x264_opt_map[jj].name) == 0)
693 // found the options that needs updating
694 opt_syns = x264_opt_map[jj].opt_syns;
695 def_val = x264_opt_map[jj].def_val;
696 type = x264_opt_map[jj].type;
697 trans = x264_opt_map[jj].translation;
701 if (opt_syns != NULL)
703 GString *x264opts = g_string_new("");
705 gchar **split = NULL;
707 gboolean foundit = FALSE;
709 options = ghb_settings_get_string(ud->settings, "x264Option");
712 split = g_strsplit(options, ":", -1);
715 for (ii = 0; split && split[ii] != NULL; ii++)
719 gchar *pos = strchr(split[ii], '=');
725 syn = find_syn_match(split[ii], opt_syns);
727 { // Updating this option
730 if (type == X264_OPT_DEBLOCK)
731 val = get_deblock_val(ud);
732 else if (type == X264_OPT_PSY)
733 val = get_psy_val(ud);
737 gval = ghb_widget_value(widget);
738 if (G_VALUE_TYPE(gval) == G_TYPE_BOOLEAN)
740 if (ghb_value_boolean(gval))
745 else if (G_VALUE_TYPE(gval) == G_TYPE_BOOLEAN)
747 // x264 doesn't accept internationalized
748 // decimal points. So force '.' when converting
753 dd = ghb_widget_double(widget);
754 val = g_strdup(g_ascii_formatd(str, 20, "%g", dd));
758 val = ghb_widget_string(widget);
760 ghb_value_free(gval);
762 if (type == X264_OPT_TRANS)
765 tmp = g_strdup(trans_ui_val(trans, val));
772 if (strcmp(def_val, val) != 0)
774 g_string_append_printf(x264opts, "%s=%s:", opt_syns[syn], val);
778 else if (val != NULL)
779 g_string_append_printf(x264opts, "%s=%s:", split[ii], val);
781 g_string_append_printf(x264opts, "%s:", split[ii]);
784 if (split) g_strfreev(split);
788 if (type == X264_OPT_DEBLOCK)
789 val = get_deblock_val(ud);
790 else if (type == X264_OPT_PSY)
791 val = get_psy_val(ud);
795 gval = ghb_widget_value(widget);
796 if (G_VALUE_TYPE(gval) == G_TYPE_BOOLEAN)
798 if (ghb_value_boolean(gval))
805 val = ghb_widget_string(widget);
807 ghb_value_free(gval);
809 if (type == X264_OPT_TRANS)
812 tmp = g_strdup(trans_ui_val(trans, val));
819 if (strcmp(def_val, val) != 0)
821 g_string_append_printf(x264opts, "%s=%s:", opt_syns[0], val);
825 // Update the options value
826 // strip the trailing ":"
829 result = g_string_free(x264opts, FALSE);
830 len = strlen(result);
831 if (len > 0) result[len - 1] = 0;
833 sopts = sanitize_x264opts(ud, result);
834 ghb_ui_update(ud, "x264Option", ghb_string_value(sopts));
835 ghb_x264_parse_options(ud, sopts);
842 x264_find_opt(gchar **opts, gchar **opt_syns)
845 for (ii = 0; opts[ii] != NULL; ii++)
848 opt = g_strdup(opts[ii]);
849 gchar *pos = strchr(opt, '=');
854 if (find_syn_match(opt, opt_syns) >= 0)
865 x264_remove_opt(gchar **opts, gchar **opt_syns)
868 for (ii = 0; opts[ii] != NULL; ii++)
871 opt = g_strdup(opts[ii]);
872 gchar *pos = strchr(opt, '=');
877 if (find_syn_match(opt, opt_syns) >= 0)
887 x264_lookup_value(gchar **opts, gchar **opt_syns)
892 const gchar *def_val = x264_opt_get_default(opt_syns[0]);
894 pos = x264_find_opt(opts, opt_syns);
897 gchar *cpos = strchr(opts[pos], '=');
900 ret = g_strdup(cpos+1);
907 else if (def_val != NULL)
909 ret = g_strdup(def_val);
915 ghb_lookup_badapt(const gchar *options)
924 split = g_strsplit(options, ":", -1);
926 result = x264_lookup_value(split, x264_badapt_syns);
930 ret = g_strtod(result, NULL);
937 ghb_lookup_aqmode(const gchar *options)
946 split = g_strsplit(options, ":", -1);
948 result = x264_lookup_value(split, x264_aqmode_syns);
952 ret = g_strtod(result, NULL);
959 ghb_lookup_bframes(const gchar *options)
968 split = g_strsplit(options, ":", -1);
970 result = x264_lookup_value(split, x264_bframes_syns);
974 ret = g_strtod(result, NULL);
981 ghb_lookup_mbtree(const gchar *options)
983 gint ret = ghb_lookup_bframes(options) != 0;
990 split = g_strsplit(options, ":", -1);
992 result = x264_lookup_value(split, x264_mbtree_syns);
996 ret = g_strtod(result, NULL);
1002 // Construct the x264 options string
1003 // The result is allocated, so someone must free it at some point.
1005 sanitize_x264opts(signal_user_data_t *ud, const gchar *options)
1007 GString *x264opts = g_string_new("");
1008 gchar **split = g_strsplit(options, ":", -1);
1011 // Fix up option dependencies
1012 gint subme = ghb_settings_combo_int(ud->settings, "x264_subme");
1015 x264_remove_opt(split, x264_psy_syns);
1017 gint trell = ghb_settings_combo_int(ud->settings, "x264_trellis");
1020 gint aqmode = ghb_lookup_aqmode(options);
1021 if (trell != 2 || aqmode == 0)
1023 gint pos = x264_find_opt(split, x264_subme_syns);
1025 split[pos] = g_strdup_printf("subme=9");
1031 gdouble psy_rd = 0., psy_trell;
1033 psy = x264_find_opt(split, x264_psy_syns);
1036 gchar *pos = strchr(split[psy], '=');
1039 x264_parse_psy(pos+1, &psy_rd, &psy_trell);
1042 split[psy] = g_strdup_printf("psy-rd=%g,0", psy_rd);
1045 gint bframes = ghb_settings_get_int(ud->settings, "x264_bframes");
1048 x264_remove_opt(split, x264_direct_syns);
1049 x264_remove_opt(split, x264_badapt_syns);
1053 x264_remove_opt(split, x264_bpyramid_syns);
1055 // Remove entries that match the defaults
1056 for (ii = 0; split[ii] != NULL; ii++)
1059 gchar *opt = g_strdup(split[ii]);
1060 gchar *pos = strchr(opt, '=');
1070 const gchar *def_val;
1071 def_val = x264_opt_get_default(opt);
1072 if (strcmp(val, def_val) == 0)
1074 // Matches the default, so remove it
1079 for (ii = 0; split[ii] != NULL; ii++)
1081 if (split[ii][0] != 0)
1082 g_string_append_printf(x264opts, "%s:", split[ii]);
1085 // strip the trailing ":"
1088 result = g_string_free(x264opts, FALSE);
1089 len = strlen(result);
1090 if (len > 0) result[len - 1] = 0;