]> git.sesse.net Git - x264/blob - gtk/x264_gtk.c
Update file headers throughout x264
[x264] / gtk / x264_gtk.c
1 /*****************************************************************************
2  * x264_gtk.c: h264 gtk encoder frontend
3  *****************************************************************************
4  * Copyright (C) 2006 Vincent Torri
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
19  *****************************************************************************/
20
21 #include <string.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <errno.h>
25 #include <math.h>
26 #if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__
27 #  include <inttypes.h>
28 #else
29 #  include <stdint.h>
30 #endif
31 #ifdef _WIN32
32 #  define _WIN32_IE   0x400
33 #  include <unistd.h>        /* for mkdir */
34 #  include <shlobj.h>        /* for SHGetSpecialFolderPath */
35 #endif
36
37 #include "../x264.h"
38
39 #include <gtk/gtk.h>
40
41 #include "x264_gtk.h"
42 #include "x264_gtk_i18n.h"
43 #include "x264_gtk_private.h"
44 #include "x264_gtk_enum.h"
45 #include "x264_gtk_bitrate.h"
46 #include "x264_gtk_rc.h"
47 #include "x264_gtk_mb.h"
48 #include "x264_gtk_more.h"
49 #include "x264_gtk_cqm.h"
50
51
52 #define CHECK_FLAG(a,flag) ((a) & (flag)) == (flag)
53 #define round(a) ( ((a)<0.0) ? (gint)(floor((a) - 0.5)) : (gint)(floor((a) + 0.5)) )
54 #define X264_MAX(a,b) ( (a)>(b) ? (a) : (b) )
55 #define X264_MIN(a,b) ( (a)<(b) ? (a) : (b) )
56
57 /* Callbacks */
58 static void x264_dialog_run (GtkDialog       *dialog,
59                          gint             response,
60                          X264_Gui_Config *gconfig,
61                          X264_Gtk        *x264_gtk);
62
63
64 /* x264 config management */
65 static void x264_default_load (GtkButton *button, gpointer user_data);
66 static void x264_current_get (X264_Gui_Config *gconfig, X264_Gtk *x264_gtk);
67 static void x264_current_set (X264_Gui_Config *gconfig, X264_Gtk *x264_gtk);
68 static void x264_default_set (X264_Gtk *x264_gtk);
69
70
71 /* Result must be freed */
72 x264_param_t *x264_gtk_param_get (X264_Gtk *x264_gtk)
73 {
74   x264_param_t *param;
75
76   if (!x264_gtk)
77     return NULL;
78
79   param = (x264_param_t *)g_malloc (sizeof (x264_param_t));
80   if (!param)
81     return NULL;
82
83   x264_param_default (param);
84
85   /* rate control */
86   param->rc.f_ip_factor = 1.0 + (double)x264_gtk->keyframe_boost / 100.0;
87   param->rc.f_pb_factor = 1.0 + (double)x264_gtk->bframes_reduction / 100.0;
88   param->rc.f_qcompress = (double)x264_gtk->bitrate_variability / 100.0;
89
90   param->rc.i_qp_min = x264_gtk->min_qp;
91   param->rc.i_qp_max = x264_gtk->max_qp;
92   param->rc.i_qp_step = x264_gtk->max_qp_step;
93
94   param->i_scenecut_threshold = x264_gtk->scene_cut_threshold;
95   param->i_keyint_min = x264_gtk->min_idr_frame_interval;
96   param->i_keyint_max = x264_gtk->max_idr_frame_interval;
97
98   param->rc.i_vbv_max_bitrate = x264_gtk->vbv_max_bitrate;
99   param->rc.i_vbv_buffer_size = x264_gtk->vbv_buffer_size;
100   param->rc.f_vbv_buffer_init = x264_gtk->vbv_buffer_init;
101
102   /* mb */
103   param->analyse.b_transform_8x8 = x264_gtk->transform_8x8;
104   param->analyse.inter = 0;
105   if (x264_gtk->pframe_search_8)
106     param->analyse.inter |= X264_ANALYSE_PSUB16x16;
107   if (x264_gtk->bframe_search_8)
108     param->analyse.inter |= X264_ANALYSE_BSUB16x16;
109   if (x264_gtk->pframe_search_4)
110     param->analyse.inter |= X264_ANALYSE_PSUB8x8;
111   if (x264_gtk->inter_search_8)
112     param->analyse.inter |= X264_ANALYSE_I8x8;
113   if (x264_gtk->inter_search_4)
114     param->analyse.inter |= X264_ANALYSE_I4x4;
115
116   param->b_bframe_pyramid = x264_gtk->bframe_pyramid && x264_gtk->bframe;
117   param->analyse.b_bidir_me = x264_gtk->bidir_me;
118   param->b_bframe_adaptive = x264_gtk->bframe_adaptive;
119   param->analyse.b_weighted_bipred = x264_gtk->weighted_bipred;
120   param->i_bframe = x264_gtk->bframe;
121   param->i_bframe_bias = x264_gtk->bframe_bias;
122   param->analyse.i_direct_mv_pred = x264_gtk->direct_mode;
123
124 /*   param->b_bframe_pyramid = param->b_bframe_pyramid && (param->i_bframe > 1); */
125
126   /* more */
127   param->analyse.i_subpel_refine = x264_gtk->partition_decision + 1;
128   param->analyse.b_bframe_rdo = x264_gtk->bframe_rdo;
129   param->analyse.i_me_method = x264_gtk->me_method;
130   param->analyse.i_me_range = x264_gtk->range;
131   param->analyse.b_chroma_me = x264_gtk->chroma_me;
132   param->analyse.i_trellis = x264_gtk->trellis;
133   param->analyse.i_noise_reduction = x264_gtk->noise_reduction;
134   param->i_frame_reference = x264_gtk->max_ref_frames;
135   param->analyse.b_mixed_references = x264_gtk->mixed_refs;
136   param->analyse.b_fast_pskip = x264_gtk->fast_pskip;
137   param->analyse.b_dct_decimate = x264_gtk->dct_decimate;
138   /* rdo : RD based mode decision for B-frames. Requires subme 6 */
139
140   param->vui.i_sar_width = x264_gtk->sample_ar_x;
141   param->vui.i_sar_height = x264_gtk->sample_ar_y;
142   param->i_threads = x264_gtk->threads;
143   param->b_cabac = x264_gtk->cabac;
144   param->b_deblocking_filter = x264_gtk->deblocking_filter;
145   param->i_deblocking_filter_alphac0 = x264_gtk->strength;
146   param->i_deblocking_filter_beta = x264_gtk->threshold;
147
148   param->i_log_level = x264_gtk->debug_method - 1;
149
150   /* cqm */
151   param->i_cqm_preset = x264_gtk->cqm_preset;
152   if (x264_gtk->cqm_file && (x264_gtk->cqm_file[0] != '\0'))
153     param->psz_cqm_file = x264_gtk->cqm_file;
154   memcpy( param->cqm_4iy, x264_gtk->cqm_4iy, 16 );
155   memcpy( param->cqm_4ic, x264_gtk->cqm_4ic, 16 );
156   memcpy( param->cqm_4py, x264_gtk->cqm_4py, 16 );
157   memcpy( param->cqm_4pc, x264_gtk->cqm_4pc, 16 );
158   memcpy( param->cqm_8iy, x264_gtk->cqm_8iy, 64 );
159   memcpy( param->cqm_8py, x264_gtk->cqm_8py, 64 );
160
161   /* bitrate */
162   switch (x264_gtk->pass) {
163   case X264_PASS_SINGLE_BITRATE:
164     param->rc.i_rc_method = X264_RC_ABR;
165     param->rc.i_bitrate  = x264_gtk->average_bitrate;
166     break;
167   case X264_PASS_SINGLE_QUANTIZER:
168     param->rc.i_rc_method = X264_RC_CQP;
169     param->rc.i_qp_constant = x264_gtk->quantizer;
170     break;
171   case X264_PASS_MULTIPASS_1ST_FAST:
172     param->analyse.i_subpel_refine = X264_MAX( X264_MIN( 3, param->analyse.i_subpel_refine - 1 ), 1 );
173     param->i_frame_reference = ( param->i_frame_reference + 1 ) >> 1;
174     param->analyse.inter &= ( ~X264_ANALYSE_PSUB8x8 );
175     param->analyse.inter &= ( ~X264_ANALYSE_BSUB16x16 );
176   case X264_PASS_MULTIPASS_1ST:
177     param->rc.i_rc_method = X264_RC_ABR;
178     param->rc.i_bitrate  = x264_gtk->average_bitrate;
179     param->rc.f_rate_tolerance = 4.0;
180     break;
181   case X264_PASS_MULTIPASS_NTH:
182     param->rc.i_rc_method = X264_RC_ABR;
183     param->rc.i_bitrate  = x264_gtk->average_bitrate;
184     param->rc.f_rate_tolerance = 1.0;
185     break;
186   }
187
188   param->rc.b_stat_write = x264_gtk->stat_write;
189   param->rc.b_stat_read = x264_gtk->stat_read;
190
191   /* FIXME: potential mem leak... */
192   param->rc.psz_stat_out = x264_gtk_path (x264_gtk->statsfile_name);
193
194   return param;
195 }
196
197 /* Result must be freed */
198 X264_Gtk *
199 x264_gtk_load (void)
200 {
201   X264_Gtk     *x264_gtk;
202   GIOChannel   *file;
203   GError       *error = NULL;
204   gchar        *filename;
205
206   x264_gtk = (X264_Gtk *)g_malloc0 (sizeof (X264_Gtk));
207   if (!x264_gtk)
208     return NULL;
209
210   filename = x264_gtk_path ("x264.cfg");
211   file = g_io_channel_new_file (filename, "r", &error);
212   if (error) {
213     g_print (_("x264.cfg: %s\n"), error->message);
214     g_print (_("Loading default configuration\n"));
215     x264_default_set (x264_gtk);
216   }
217   else {
218     GIOStatus status;
219     gchar    *data = NULL;
220     gsize     length;
221
222     g_print (_("Loading configuration from %s\n"), filename);
223     g_io_channel_set_encoding (file, NULL, NULL);
224     status = g_io_channel_read_to_end (file, &data, &length, &error);
225     if ((status == G_IO_STATUS_NORMAL) &&
226         (length == sizeof (X264_Gtk))) {
227       memcpy (x264_gtk, data, length);
228     }
229     g_io_channel_shutdown (file, TRUE, NULL);
230     g_io_channel_unref (file);
231   }
232   g_free (filename);
233
234   return x264_gtk;
235 }
236
237 GtkWidget *
238 x264_gtk_window_create (GtkWidget *parent)
239 {
240   GtkWidget       *win_x264_gtk;
241   GtkWidget       *notebook;
242   GtkWidget       *page;
243   GtkWidget       *button;
244   GtkWidget       *label;
245   X264_Gui_Config *gconfig;
246   X264_Gtk        *x264_gtk;
247   gint             result;
248   GtkDialogFlags   flags = 0;
249
250   gconfig = (X264_Gui_Config *)g_malloc (sizeof (X264_Gui_Config));
251   if (!gconfig)
252     return NULL;
253
254   x264_gtk = x264_gtk_load ();
255
256   if (parent)
257     flags = GTK_DIALOG_MODAL |GTK_DIALOG_DESTROY_WITH_PARENT;
258   win_x264_gtk = gtk_dialog_new_with_buttons (_("X264 Configuration"),
259                                               GTK_WINDOW (parent),
260                                               flags,
261                                               NULL);
262
263   button = gtk_button_new_with_label (_("Default"));
264   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (win_x264_gtk)->action_area), button, FALSE, TRUE, 6);
265   g_signal_connect (G_OBJECT (button),
266                     "clicked",
267                     G_CALLBACK (x264_default_load),
268                     gconfig);
269   gtk_widget_show (button);
270
271   gtk_dialog_add_buttons (GTK_DIALOG (win_x264_gtk),
272                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
273                           GTK_STOCK_OK, GTK_RESPONSE_OK,
274                           NULL);
275
276   g_object_set_data (G_OBJECT (win_x264_gtk), "x264-gui-config", gconfig);
277   g_object_set_data (G_OBJECT (win_x264_gtk), "x264-config", x264_gtk);
278   gtk_window_set_resizable (GTK_WINDOW (win_x264_gtk), FALSE);
279
280   notebook = gtk_notebook_new ();
281   gtk_container_add (GTK_CONTAINER (GTK_DIALOG (win_x264_gtk)->vbox), notebook);
282   gtk_widget_show (notebook);
283
284   label = gtk_label_new (_("Bitrate"));
285   gtk_widget_show (label);
286
287   page = x264_bitrate_page (gconfig);
288   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
289   gtk_widget_show (page);
290
291   label = gtk_label_new (_("Rate Control"));
292   gtk_widget_show (label);
293
294   page = x264_rate_control_page (gconfig);
295   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
296   gtk_widget_show (page);
297
298   label = gtk_label_new (_("MB & Frames"));
299   gtk_widget_show (label);
300
301   page = x264_mb_page (gconfig);
302   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
303   gtk_widget_show (page);
304
305   label = gtk_label_new (_("More..."));
306   gtk_widget_show (label);
307
308   page = x264_more_page (gconfig);
309   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
310   gtk_widget_show (page);
311
312   label = gtk_label_new (_("Quantization matrices"));
313   gtk_widget_show (label);
314
315   page = x264_cqm_page (gconfig);
316   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
317   gtk_widget_show (page);
318
319   x264_current_set (gconfig, x264_gtk);
320
321   result = gtk_dialog_run (GTK_DIALOG (win_x264_gtk));
322   x264_dialog_run (GTK_DIALOG (win_x264_gtk), result, gconfig, x264_gtk);
323
324   return win_x264_gtk;
325 }
326
327 void
328 x264_gtk_shutdown (GtkWidget *dialog)
329 {
330   X264_Gui_Config *gconfig;
331
332   gconfig = g_object_get_data (G_OBJECT (dialog), "x264-gui-config");
333   gtk_widget_destroy (dialog);
334   if (gconfig)
335     g_free (gconfig);
336 }
337
338 void
339 x264_gtk_free (X264_Gtk *x264_gtk)
340 {
341   if (!x264_gtk)
342     return;
343
344   g_free (x264_gtk);
345 }
346
347
348 /* Notebook pages */
349
350 /* Callbacks */
351
352 static void
353 x264_dialog_run (GtkDialog       *dialog UNUSED,
354              gint             response,
355              X264_Gui_Config *gconfig,
356              X264_Gtk        *x264_gtk)
357 {
358   if (response == GTK_RESPONSE_OK)
359     {
360       GIOChannel *file;
361       gchar      *filename;
362       gchar      *dir;
363       gsize       length;
364       gint        res;
365 #ifndef _WIN32
366       mode_t      mode;
367 #endif
368
369       dir = x264_gtk_path (NULL);
370
371 #ifdef _WIN32
372       res = mkdir (dir);
373 #else
374       mode =
375         S_IRUSR | S_IXUSR | S_IWUSR |
376         S_IRGRP | S_IXGRP | S_IWGRP |
377         S_IROTH | S_IXOTH | S_IWOTH;
378       res = mkdir (dir, mode);
379 #endif /* _WIN32 */
380       if (res != 0 && errno != EEXIST)
381         {
382           g_free (dir);
383
384           return;
385         }
386
387       filename = x264_gtk_path ("x264.cfg");
388       g_print (_("Writing configuration to %s\n"), filename);
389       file = g_io_channel_new_file (filename, "w+", NULL);
390       if (file)
391         {
392           x264_current_get (gconfig, x264_gtk);
393           g_io_channel_set_encoding (file, NULL, NULL);
394           g_io_channel_write_chars (file, (const gchar *)x264_gtk,
395                                     sizeof (X264_Gtk), &length, NULL);
396           g_io_channel_unref (file);
397         }
398       g_free (filename);
399       g_free (dir);
400     }
401 }
402
403 /* x264 config management */
404 static void
405 x264_default_load (GtkButton *button UNUSED, gpointer user_data)
406 {
407   gchar            buf[64];
408   X264_Gui_Config *config;
409   x264_param_t     param;
410   gint             i;
411
412   if (!user_data)
413     return;
414
415   config = (X264_Gui_Config *)user_data;
416
417   x264_param_default (&param);
418
419   /* bitrate */
420   gtk_combo_box_set_active (GTK_COMBO_BOX (config->bitrate.pass), 1);
421   g_snprintf (buf, 64, "%d", param.rc.i_bitrate);
422   gtk_entry_set_text (GTK_ENTRY (config->bitrate.w_average_bitrate), buf);
423   gtk_entry_set_text (GTK_ENTRY (config->bitrate.w_target_bitrate), buf);
424   gtk_range_set_range (GTK_RANGE (config->bitrate.w_quantizer),
425                        0.0,
426                        51.0);
427   gtk_range_set_value (GTK_RANGE (config->bitrate.w_quantizer),
428                        (gdouble)param.rc.i_qp_constant);
429   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->bitrate.update_statfile), FALSE);
430   gtk_entry_set_text (GTK_ENTRY (config->bitrate.statsfile_name), "x264.stats");
431   gtk_widget_set_sensitive (config->bitrate.statsfile_name, FALSE);
432   gtk_widget_set_sensitive (config->bitrate.update_statfile, FALSE);
433
434   /* rate control */
435   g_snprintf (buf, 64, "%d", round((param.rc.f_ip_factor - 1.0) * 100));
436   gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.keyframe_boost), buf);
437   g_snprintf (buf, 64, "%d", round((param.rc.f_pb_factor - 1.0) * 100));
438   gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.bframes_reduction), buf);
439   g_snprintf (buf, 64, "%d", (gint)(param.rc.f_qcompress * 100));
440   gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.bitrate_variability), buf);
441
442   g_snprintf (buf, 64, "%d", param.rc.i_qp_min);
443   gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.min_qp), buf);
444   g_snprintf (buf, 64, "%d", param.rc.i_qp_max);
445   gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.max_qp), buf);
446   g_snprintf (buf, 64, "%d", param.rc.i_qp_step);
447   gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.max_qp_step), buf);
448
449   g_snprintf (buf, 64, "%d", param.i_scenecut_threshold);
450   gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.scene_cut_threshold), buf);
451   g_snprintf (buf, 64, "%d", param.i_keyint_min);
452   gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.min_idr_frame_interval), buf);
453   g_snprintf (buf, 64, "%d", param.i_keyint_max);
454   gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.max_idr_frame_interval), buf);
455
456   g_snprintf (buf, 64, "%d", param.rc.i_vbv_max_bitrate);
457   gtk_entry_set_text (GTK_ENTRY (config->rate_control.vbv.vbv_max_bitrate), buf);
458   g_snprintf (buf, 64, "%d", param.rc.i_vbv_buffer_size);
459   gtk_entry_set_text (GTK_ENTRY (config->rate_control.vbv.vbv_buffer_size), buf);
460   g_snprintf (buf, 64, "%.1f", param.rc.f_vbv_buffer_init);
461   gtk_entry_set_text (GTK_ENTRY (config->rate_control.vbv.vbv_buffer_init), buf);
462
463   /* mb */
464   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.transform_8x8), param.analyse.b_transform_8x8);
465   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_8), CHECK_FLAG(param.analyse.inter, X264_ANALYSE_PSUB16x16));
466   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.bframe_search_8), CHECK_FLAG(param.analyse.inter, X264_ANALYSE_BSUB16x16));
467   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_4), CHECK_FLAG(param.analyse.inter, X264_ANALYSE_PSUB8x8));
468   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_8), CHECK_FLAG(param.analyse.inter, X264_ANALYSE_I8x8));
469   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_4), CHECK_FLAG(param.analyse.inter, X264_ANALYSE_I4x4));
470
471   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.bframe_pyramid), param.b_bframe_pyramid);
472   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.bidir_me), param.analyse.b_bidir_me);
473   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.bframe_adaptive), param.b_bframe_adaptive);
474   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.weighted_bipred), param.analyse.b_weighted_bipred);
475   g_snprintf (buf, 64, "%d", param.i_bframe);
476   gtk_entry_set_text (GTK_ENTRY (config->mb.bframes.bframe), buf);
477   gtk_range_set_value (GTK_RANGE (config->mb.bframes.bframe_bias), (gdouble)param.i_bframe_bias);
478   gtk_combo_box_set_active (GTK_COMBO_BOX (config->mb.bframes.direct_mode), param.analyse.i_direct_mv_pred);
479
480   /* more */
481   if (param.analyse.b_bframe_rdo)
482     gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision), X264_PD_6b);
483   else
484     gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision), param.analyse.i_subpel_refine - 1);
485   gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.method), param.analyse.i_me_method);
486   g_snprintf (buf, 64, "%d", param.analyse.i_me_range);
487   gtk_entry_set_text (GTK_ENTRY (config->more.motion_estimation.range), buf);
488   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.chroma_me), param.analyse.b_chroma_me);
489   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.mixed_refs), param.analyse.b_mixed_references);
490   g_snprintf (buf, 64, "%d", param.i_frame_reference);
491   gtk_entry_set_text (GTK_ENTRY (config->more.motion_estimation.max_ref_frames), buf);
492   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.fast_pskip), param.analyse.b_fast_pskip);
493   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.dct_decimate), param.analyse.b_dct_decimate);
494
495   g_snprintf (buf, 64, "%d", param.vui.i_sar_width);
496   gtk_entry_set_text (GTK_ENTRY (config->more.misc.sample_ar_x), buf);
497   g_snprintf (buf, 64, "%d", param.vui.i_sar_height);
498   gtk_entry_set_text (GTK_ENTRY (config->more.misc.sample_ar_y), buf);
499   gtk_spin_button_set_value (GTK_SPIN_BUTTON (config->more.misc.threads), param.i_threads);
500   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.cabac), param.b_cabac);
501   gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.misc.trellis), param.analyse.i_trellis);
502   g_snprintf (buf, 64, "%d", param.analyse.i_noise_reduction);
503   gtk_entry_set_text (GTK_ENTRY (config->more.misc.noise_reduction), buf);
504   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.df.deblocking_filter), param.b_deblocking_filter);
505   gtk_range_set_value (GTK_RANGE (config->more.misc.df.strength), (gdouble)param.i_deblocking_filter_alphac0);
506   gtk_range_set_value (GTK_RANGE (config->more.misc.df.threshold), (gdouble)param.i_deblocking_filter_beta);
507
508   gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.debug.log_level), param.i_log_level + 1);
509   gtk_entry_set_text (GTK_ENTRY (config->more.debug.fourcc), "H264");
510
511   /* cqm */
512   switch (param.i_cqm_preset) {
513   case X264_CQM_FLAT:
514     // workaround: gtk fails to update the matrix entries if we activate the button
515     // that was already active.
516     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->cqm.radio_jvt), TRUE);
517     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->cqm.radio_flat), TRUE);
518     break;
519   case X264_CQM_JVT:
520     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->cqm.radio_jvt), TRUE);
521     break;
522   case X264_CQM_CUSTOM:
523     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->cqm.radio_custom), TRUE);
524     break;
525   }
526   if (param.psz_cqm_file && (param.psz_cqm_file[0] != '\0'))
527     gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (config->cqm.cqm_file), param.psz_cqm_file);
528   for (i = 0; i < 16; i++) {
529     gchar buf[4];
530
531     g_snprintf (buf, 4, "%d", param.cqm_4iy[i]);
532     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_4iy[i]), buf);
533     g_snprintf (buf, 4, "%d", param.cqm_4ic[i]);
534     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_4ic[i]), buf);
535     g_snprintf (buf, 4, "%d", param.cqm_4py[i]);
536     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_4py[i]), buf);
537     g_snprintf (buf, 4, "%d", param.cqm_4pc[i]);
538     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_4pc[i]), buf);
539   }
540   for (i = 0; i < 64; i++) {
541     gchar buf[4];
542
543     g_snprintf (buf, 4, "%d", param.cqm_8iy[i]);
544     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_8iy[i]), buf);
545     g_snprintf (buf, 4, "%d", param.cqm_8py[i]);
546     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_8py[i]), buf);
547   }
548 }
549
550 static void
551 x264_default_set (X264_Gtk *x264_gtk)
552 {
553   x264_param_t param;
554
555   x264_param_default (&param);
556
557   /* bitrate */
558   x264_gtk->pass = X264_PASS_SINGLE_QUANTIZER;
559   x264_gtk->average_bitrate = param.rc.i_bitrate;
560   x264_gtk->target_bitrate = param.rc.i_bitrate;
561   x264_gtk->quantizer = param.rc.i_qp_constant;
562   x264_gtk->stat_write = param.rc.b_stat_write;
563   x264_gtk->stat_read = param.rc.b_stat_read;
564   x264_gtk->update_statfile = 0;
565   x264_gtk->statsfile_length = strlen (param.rc.psz_stat_out);
566   memcpy (x264_gtk->statsfile_name, param.rc.psz_stat_out, x264_gtk->statsfile_length + 1);
567
568   /* rate control */
569   x264_gtk->keyframe_boost = round((param.rc.f_ip_factor - 1.0) * 100);
570   x264_gtk->bframes_reduction = round((param.rc.f_pb_factor - 1.0) * 100);
571   x264_gtk->bitrate_variability = round(param.rc.f_qcompress * 100);
572
573   x264_gtk->min_qp = param.rc.i_qp_min;
574   x264_gtk->max_qp = param.rc.i_qp_max;
575   x264_gtk->max_qp_step = param.rc.i_qp_step;
576
577   x264_gtk->scene_cut_threshold = param.i_scenecut_threshold;
578   x264_gtk->min_idr_frame_interval = param.i_keyint_min;
579   x264_gtk->max_idr_frame_interval = param.i_keyint_max;
580
581   x264_gtk->vbv_max_bitrate = param.rc.i_vbv_max_bitrate;
582   x264_gtk->vbv_buffer_size = param.rc.i_vbv_buffer_size;
583   x264_gtk->vbv_buffer_init = param.rc.f_vbv_buffer_init;
584
585   /* mb */
586   x264_gtk->transform_8x8 = param.analyse.b_transform_8x8;
587
588   if (CHECK_FLAG(param.analyse.inter, X264_ANALYSE_PSUB16x16))
589     x264_gtk->pframe_search_8 = 1;
590   else
591     x264_gtk->pframe_search_8 = 0;
592   if (CHECK_FLAG(param.analyse.inter, X264_ANALYSE_BSUB16x16))
593     x264_gtk->bframe_search_8 = 1;
594   else
595     x264_gtk->bframe_search_8 = 0;
596   if (CHECK_FLAG(param.analyse.inter, X264_ANALYSE_PSUB8x8))
597     x264_gtk->pframe_search_4 = 1;
598   else
599     x264_gtk->pframe_search_4 = 0;
600   x264_gtk->inter_search_8 = CHECK_FLAG(param.analyse.inter, X264_ANALYSE_I8x8);
601   x264_gtk->inter_search_4 = CHECK_FLAG(param.analyse.inter, X264_ANALYSE_I4x4);
602
603   x264_gtk->bframe_pyramid = param.b_bframe_pyramid;
604   x264_gtk->bidir_me = param.analyse.b_bidir_me;
605   x264_gtk->bframe_adaptive = param.b_bframe_adaptive;
606   x264_gtk->weighted_bipred = param.analyse.b_weighted_bipred;
607   x264_gtk->bframe = param.i_bframe;
608   x264_gtk->bframe_bias = param.i_bframe_bias;
609   x264_gtk->direct_mode = param.analyse.i_direct_mv_pred;
610
611   /* more */
612   x264_gtk->bframe_rdo = param.analyse.b_bframe_rdo;
613   x264_gtk->partition_decision = param.analyse.i_subpel_refine - 1;
614   x264_gtk->me_method = param.analyse.i_me_method;
615   x264_gtk->range = param.analyse.i_me_range;
616   x264_gtk->chroma_me = param.analyse.b_chroma_me;
617   x264_gtk->max_ref_frames = param.i_frame_reference;
618   x264_gtk->mixed_refs = param.analyse.b_mixed_references;
619   x264_gtk->fast_pskip = param.analyse.b_fast_pskip;
620   x264_gtk->dct_decimate = param.analyse.b_dct_decimate;
621
622   x264_gtk->sample_ar_x = param.vui.i_sar_width;
623   x264_gtk->sample_ar_y = param.vui.i_sar_height;
624   x264_gtk->threads = param.i_threads;
625   x264_gtk->cabac = param.b_cabac;
626   x264_gtk->trellis = param.analyse.i_trellis;
627   x264_gtk->noise_reduction = param.analyse.i_noise_reduction;
628   x264_gtk->deblocking_filter = param.b_deblocking_filter;
629   x264_gtk->strength = param.i_deblocking_filter_alphac0;
630   x264_gtk->threshold = param.i_deblocking_filter_beta;
631
632   x264_gtk->debug_method = param.i_log_level + 1;
633   memcpy (x264_gtk->fourcc, "H264", 5);
634
635   /* cqm */
636   x264_gtk->cqm_preset = param.i_cqm_preset;
637   if (param.psz_cqm_file && (param.psz_cqm_file[0] != '\0'))
638     memcpy (x264_gtk->cqm_file, param.psz_cqm_file,  strlen (param.psz_cqm_file) + 1);
639   memcpy (x264_gtk->cqm_4iy, param.cqm_4iy, 16);
640   memcpy (x264_gtk->cqm_4ic, param.cqm_4ic, 16);
641   memcpy (x264_gtk->cqm_4py, param.cqm_4py, 16);
642   memcpy (x264_gtk->cqm_4pc, param.cqm_4pc, 16);
643   memcpy (x264_gtk->cqm_8iy, param.cqm_8iy, 64);
644   memcpy (x264_gtk->cqm_8py, param.cqm_8py, 64);
645 }
646
647 static void
648 x264_current_set (X264_Gui_Config *config, X264_Gtk *x264_gtk)
649 {
650   gchar buf[4096];
651   gint  i;
652
653   if (!config)
654     return;
655
656   /* bitrate */
657   gtk_combo_box_set_active (GTK_COMBO_BOX (config->bitrate.pass), x264_gtk->pass);
658   g_snprintf (buf, 5, "%d", x264_gtk->average_bitrate);
659   gtk_entry_set_text (GTK_ENTRY (config->bitrate.w_average_bitrate), buf);
660   gtk_range_set_range (GTK_RANGE (config->bitrate.w_quantizer),
661                        0.0,
662                        51.0);
663   gtk_range_set_value (GTK_RANGE (config->bitrate.w_quantizer), x264_gtk->quantizer);
664   g_snprintf (buf, 5, "%d", x264_gtk->target_bitrate);
665   gtk_entry_set_text (GTK_ENTRY (config->bitrate.w_target_bitrate), buf);
666   switch (gtk_combo_box_get_active (GTK_COMBO_BOX (config->bitrate.pass)))
667   {
668   case 0:
669   case 1:
670     gtk_widget_set_sensitive (config->bitrate.update_statfile, FALSE);
671     gtk_widget_set_sensitive (config->bitrate.statsfile_name, FALSE);
672     break;
673   case 2:
674   case 3:
675   case 4:
676   default:
677     gtk_widget_set_sensitive (config->bitrate.update_statfile, TRUE);
678     break;
679   }
680   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->bitrate.update_statfile), x264_gtk->update_statfile);
681   gtk_entry_set_text (GTK_ENTRY (config->bitrate.statsfile_name), x264_gtk->statsfile_name);
682   if (x264_gtk->update_statfile)
683     gtk_widget_set_sensitive (config->bitrate.statsfile_name, TRUE);
684   else
685     gtk_widget_set_sensitive (config->bitrate.statsfile_name, FALSE);
686
687   /* rate control */
688   g_snprintf (buf, 5, "%d", x264_gtk->keyframe_boost);
689   gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.keyframe_boost), buf);
690   g_snprintf (buf, 5, "%d", x264_gtk->bframes_reduction);
691   gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.bframes_reduction), buf);
692   g_snprintf (buf, 5, "%d", x264_gtk->bitrate_variability);
693   gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.bitrate_variability), buf);
694
695   g_snprintf (buf, 5, "%d", x264_gtk->min_qp);
696   gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.min_qp), buf);
697   g_snprintf (buf, 5, "%d", x264_gtk->max_qp);
698   gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.max_qp), buf);
699   g_snprintf (buf, 5, "%d", x264_gtk->max_qp_step);
700   gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.max_qp_step), buf);
701
702   g_snprintf (buf, 5, "%d", x264_gtk->scene_cut_threshold);
703   gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.scene_cut_threshold), buf);
704   g_snprintf (buf, 5, "%d", x264_gtk->min_idr_frame_interval);
705   gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.min_idr_frame_interval), buf);
706   g_snprintf (buf, 5, "%d", x264_gtk->max_idr_frame_interval);
707   gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.max_idr_frame_interval), buf);
708
709   g_snprintf (buf, 5, "%d", x264_gtk->vbv_max_bitrate);
710   gtk_entry_set_text (GTK_ENTRY (config->rate_control.vbv.vbv_max_bitrate), buf);
711   g_snprintf (buf, 5, "%d", x264_gtk->vbv_buffer_size);
712   gtk_entry_set_text (GTK_ENTRY (config->rate_control.vbv.vbv_buffer_size), buf);
713   g_snprintf (buf, 5, "%.1f", x264_gtk->vbv_buffer_init);
714   gtk_entry_set_text (GTK_ENTRY (config->rate_control.vbv.vbv_buffer_init), buf);
715
716   /* mb */
717   if (x264_gtk->transform_8x8)
718     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.transform_8x8), TRUE);
719   else
720     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.transform_8x8), FALSE);
721   if (x264_gtk->pframe_search_8)
722     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_8), TRUE);
723   else
724     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_8), FALSE);
725   if (x264_gtk->bframe_search_8)
726     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.bframe_search_8), TRUE);
727   else
728     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.bframe_search_8), FALSE);
729   if (x264_gtk->pframe_search_4)
730     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_4), TRUE);
731   else
732     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_4), FALSE);
733   if (x264_gtk->inter_search_8)
734     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_8), TRUE);
735   else
736     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_8), FALSE);
737   if (x264_gtk->inter_search_4)
738     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_4), TRUE);
739   else
740     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_4), FALSE);
741
742   /* mb - bframes */
743   if (x264_gtk->bframe_pyramid)
744     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.bframe_pyramid), TRUE);
745   else
746     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.bframe_pyramid), FALSE);
747   if (x264_gtk->bidir_me)
748     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.bidir_me), TRUE);
749   else
750     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.bidir_me), FALSE);
751   if (x264_gtk->bframe_adaptive)
752     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.bframe_adaptive), TRUE);
753   else
754     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.bframe_adaptive), FALSE);
755   if (x264_gtk->weighted_bipred)
756     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.weighted_bipred), TRUE);
757   else
758     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.weighted_bipred), FALSE);
759   g_snprintf (buf, 5, "%d", x264_gtk->bframe);
760   gtk_entry_set_text (GTK_ENTRY (config->mb.bframes.bframe), buf);
761   gtk_range_set_value (GTK_RANGE (config->mb.bframes.bframe_bias), (gdouble)x264_gtk->bframe_bias);
762   gtk_combo_box_set_active (GTK_COMBO_BOX (config->mb.bframes.direct_mode), x264_gtk->direct_mode);
763
764   /* more */
765   if (x264_gtk->bframe_rdo)
766     gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision), X264_PD_6b);
767   else
768     gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision), x264_gtk->partition_decision);
769   gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.method), x264_gtk->me_method);
770   g_snprintf (buf, 5, "%d", x264_gtk->range);
771   gtk_entry_set_text (GTK_ENTRY (config->more.motion_estimation.range), buf);
772   if (x264_gtk->chroma_me)
773     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.chroma_me), TRUE);
774   else
775     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.chroma_me), FALSE);
776   g_snprintf (buf, 5, "%d", x264_gtk->max_ref_frames);
777   gtk_entry_set_text (GTK_ENTRY (config->more.motion_estimation.max_ref_frames), buf);
778   if (x264_gtk->mixed_refs && (x264_gtk->max_ref_frames >= 2))
779     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.mixed_refs), TRUE);
780   else
781     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.mixed_refs), FALSE);
782   if (x264_gtk->fast_pskip)
783     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.fast_pskip), TRUE);
784   else
785     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.fast_pskip), FALSE);
786   if (x264_gtk->dct_decimate)
787     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.dct_decimate), TRUE);
788   else
789     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.dct_decimate), FALSE);
790
791   g_snprintf (buf, 5, "%d", x264_gtk->sample_ar_x);
792   gtk_entry_set_text (GTK_ENTRY (config->more.misc.sample_ar_x), buf);
793   g_snprintf (buf, 5, "%d", x264_gtk->sample_ar_y);
794   gtk_entry_set_text (GTK_ENTRY (config->more.misc.sample_ar_y), buf);
795   gtk_spin_button_set_value (GTK_SPIN_BUTTON (config->more.misc.threads), x264_gtk->threads);
796   if (x264_gtk->cabac)
797     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.cabac), TRUE);
798   else
799     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.cabac), FALSE);
800   gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.misc.trellis), x264_gtk->trellis);
801   g_snprintf (buf, 64, "%d", x264_gtk->noise_reduction);
802   gtk_entry_set_text (GTK_ENTRY (config->more.misc.noise_reduction), buf);
803   if (x264_gtk->deblocking_filter)
804     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.df.deblocking_filter), TRUE);
805   else
806     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.df.deblocking_filter), FALSE);
807   gtk_range_set_value (GTK_RANGE (config->more.misc.df.strength), (gdouble)x264_gtk->strength);
808   gtk_range_set_value (GTK_RANGE (config->more.misc.df.threshold), (gdouble)x264_gtk->threshold);
809
810   gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.debug.log_level), x264_gtk->debug_method);
811   gtk_entry_set_text (GTK_ENTRY (config->more.debug.fourcc), x264_gtk->fourcc);
812
813   /* cqm */
814   switch (x264_gtk->cqm_preset) {
815   case X264_CQM_PRESET_FLAT:
816     // workaround: gtk fails to update the matrix entries if we activate the button
817     // that was already active.
818     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->cqm.radio_jvt), TRUE);
819     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->cqm.radio_flat), TRUE);
820     break;
821   case X264_CQM_PRESET_JVT:
822     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->cqm.radio_jvt), TRUE);
823     break;
824   case X264_CQM_PRESET_CUSTOM:
825     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->cqm.radio_custom), TRUE);
826     break;
827   }
828   if (x264_gtk->cqm_file && (x264_gtk->cqm_file[0] != '\0'))
829     gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (config->cqm.cqm_file), x264_gtk->cqm_file);
830   for (i = 0; i < 16; i++) {
831     gchar buf[4];
832
833     g_snprintf (buf, 4, "%d", x264_gtk->cqm_4iy[i]);
834     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_4iy[i]), buf);
835     g_snprintf (buf, 4, "%d", x264_gtk->cqm_4ic[i]);
836     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_4ic[i]), buf);
837     g_snprintf (buf, 4, "%d", x264_gtk->cqm_4py[i]);
838     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_4py[i]), buf);
839     g_snprintf (buf, 4, "%d", x264_gtk->cqm_4pc[i]);
840     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_4pc[i]), buf);
841   }
842   for (i = 0; i < 64; i++) {
843     gchar buf[4];
844
845     g_snprintf (buf, 4, "%d", x264_gtk->cqm_8iy[i]);
846     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_8iy[i]), buf);
847     g_snprintf (buf, 4, "%d", x264_gtk->cqm_8py[i]);
848     gtk_entry_set_text (GTK_ENTRY (config->cqm.cqm_8py[i]), buf);
849   }
850 }
851
852 static void
853 x264_current_get (X264_Gui_Config *gconfig, X264_Gtk *x264_gtk)
854 {
855   const gchar *text;
856   gint         i;
857
858   if (!gconfig)
859     return;
860
861   if (!x264_gtk)
862     g_print (_("problem...\n"));
863
864   /* bitrate */
865   switch (gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->bitrate.pass)))
866   {
867   case 0:
868     x264_gtk->pass = X264_PASS_SINGLE_BITRATE;
869     text = gtk_entry_get_text (GTK_ENTRY (gconfig->bitrate.w_average_bitrate));
870     x264_gtk->average_bitrate = (gint)g_ascii_strtoull (text, NULL, 10);
871     x264_gtk->stat_write = 0;
872     x264_gtk->stat_read = 0;
873     break;
874   case 1:
875     x264_gtk->pass = X264_PASS_SINGLE_QUANTIZER;
876     x264_gtk->quantizer = (gint)gtk_range_get_value (GTK_RANGE (gconfig->bitrate.w_quantizer));
877     x264_gtk->stat_write = 0;
878     x264_gtk->stat_read = 0;
879     break;
880   case 2:
881     x264_gtk->pass = X264_PASS_MULTIPASS_1ST;
882     text = gtk_entry_get_text (GTK_ENTRY (gconfig->bitrate.w_target_bitrate));
883     x264_gtk->target_bitrate = (gint)g_ascii_strtoull (text, NULL, 10);
884     x264_gtk->stat_write = 1;
885     break;
886   case 3:
887     x264_gtk->pass = X264_PASS_MULTIPASS_1ST_FAST;
888     text = gtk_entry_get_text (GTK_ENTRY (gconfig->bitrate.w_target_bitrate));
889     x264_gtk->target_bitrate = (gint)g_ascii_strtoull (text, NULL, 10);
890     x264_gtk->stat_write = 1;
891     break;
892   case 4:
893   default:
894     x264_gtk->pass = X264_PASS_MULTIPASS_NTH;
895     text = gtk_entry_get_text (GTK_ENTRY (gconfig->bitrate.w_target_bitrate));
896     x264_gtk->target_bitrate = (gint)g_ascii_strtoull (text, NULL, 10);
897     x264_gtk->stat_read = 1;
898     if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->bitrate.update_statfile)))
899       x264_gtk->stat_write = 1;
900     break;
901   }
902   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->bitrate.update_statfile)))
903     x264_gtk->update_statfile = 1;
904   else
905     x264_gtk->update_statfile = 0;
906
907   text = gtk_entry_get_text (GTK_ENTRY (gconfig->bitrate.statsfile_name));
908   x264_gtk->statsfile_length = strlen (text);
909   memcpy (x264_gtk->statsfile_name,
910           text,
911           x264_gtk->statsfile_length + 1);
912
913   /* rate control */
914   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.bitrate.keyframe_boost));
915   x264_gtk->keyframe_boost = (gint)g_ascii_strtoull (text, NULL, 10);
916
917   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.bitrate.bframes_reduction));
918   x264_gtk->bframes_reduction = (gint)g_ascii_strtoull (text, NULL, 10);
919   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.bitrate.bitrate_variability));
920   x264_gtk->bitrate_variability = (gint)g_ascii_strtoull (text, NULL, 10);
921
922   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.quantization_limits.min_qp));
923   x264_gtk->min_qp = (gint)g_ascii_strtoull (text, NULL, 10);
924   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.quantization_limits.max_qp));
925   x264_gtk->max_qp = (gint)g_ascii_strtoull (text, NULL, 10);
926   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.quantization_limits.max_qp_step));
927   x264_gtk->max_qp_step = (gint)g_ascii_strtoull (text, NULL, 10);
928
929   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.scene_cuts.scene_cut_threshold));
930   x264_gtk->scene_cut_threshold = (gint)g_ascii_strtoull (text, NULL, 10);
931   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.scene_cuts.min_idr_frame_interval));
932   x264_gtk->min_idr_frame_interval = (gint)g_ascii_strtoull (text, NULL, 10);
933   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.scene_cuts.max_idr_frame_interval));
934   x264_gtk->max_idr_frame_interval = (gint)g_ascii_strtoull (text, NULL, 10);
935
936   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.vbv.vbv_max_bitrate));
937   x264_gtk->vbv_max_bitrate = (gint)g_ascii_strtoull (text, NULL, 10);
938   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.vbv.vbv_buffer_size));
939   x264_gtk->vbv_buffer_size = (gint)g_ascii_strtoull (text, NULL, 10);
940   text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.vbv.vbv_buffer_init));
941   x264_gtk->vbv_buffer_init = (gint)g_ascii_strtoull (text, NULL, 10);
942
943   /* mb */
944   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.transform_8x8)))
945     x264_gtk->transform_8x8 = 1;
946   else
947     x264_gtk->transform_8x8 = 0;
948   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.pframe_search_8)))
949     x264_gtk->pframe_search_8 = 1;
950   else
951     x264_gtk->pframe_search_8 = 0;
952   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.bframe_search_8)))
953     x264_gtk->bframe_search_8 = 1;
954   else
955     x264_gtk->bframe_search_8 = 0;
956   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.pframe_search_4)))
957     x264_gtk->pframe_search_4 = 1;
958   else
959     x264_gtk->pframe_search_4 = 0;
960   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.inter_search_8)))
961     x264_gtk->inter_search_8 = 1;
962   else
963     x264_gtk->inter_search_8 = 0;
964   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.inter_search_4)))
965     x264_gtk->inter_search_4 = 1;
966   else
967     x264_gtk->inter_search_4 = 0;
968
969   /* mb - bframes */
970   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.bframes.bframe_pyramid)))
971     x264_gtk->bframe_pyramid = 1;
972   else
973     x264_gtk->bframe_pyramid = 0;
974   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.bframes.bidir_me)))
975     x264_gtk->bidir_me = 1;
976   else
977     x264_gtk->bidir_me = 0;
978   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.bframes.bframe_adaptive)))
979     x264_gtk->bframe_adaptive = 1;
980   else
981     x264_gtk->bframe_adaptive = 0;
982   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.bframes.weighted_bipred)))
983     x264_gtk->weighted_bipred = 1;
984   else
985     x264_gtk->weighted_bipred = 0;
986   text = gtk_entry_get_text (GTK_ENTRY (gconfig->mb.bframes.bframe));
987   x264_gtk->bframe = (gint)g_ascii_strtoull (text, NULL, 10);
988   x264_gtk->bframe_bias = (gint)gtk_range_get_value (GTK_RANGE (gconfig->mb.bframes.bframe_bias));
989
990   switch (gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->mb.bframes.direct_mode)))
991     {
992     case 0:
993       x264_gtk->direct_mode = X264_NONE;
994     case 1:
995       x264_gtk->direct_mode = X264_SPATIAL;
996       break;
997     case 2:
998       x264_gtk->direct_mode = X264_TEMPORAL;
999       break;
1000     default:
1001       x264_gtk->direct_mode = X264_AUTO;
1002       break;
1003     }
1004
1005   /* more */
1006   switch (gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->more.motion_estimation.partition_decision)))
1007     {
1008     case 0:
1009       x264_gtk->partition_decision = X264_PD_1;
1010       break;
1011     case 1:
1012       x264_gtk->partition_decision = X264_PD_2;
1013       break;
1014     case 2:
1015       x264_gtk->partition_decision = X264_PD_3;
1016       break;
1017     case 3:
1018       x264_gtk->partition_decision = X264_PD_4;
1019       break;
1020     case 4:
1021       x264_gtk->partition_decision = X264_PD_5;
1022       break;
1023     case 5:
1024       x264_gtk->partition_decision = X264_PD_6;
1025       break;
1026     default:
1027       x264_gtk->partition_decision = X264_PD_6;
1028       x264_gtk->bframe_rdo = 1;
1029       break;
1030     }
1031   switch (gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->more.motion_estimation.method)))
1032     {
1033     case 0:
1034       x264_gtk->me_method = X264_ME_METHOD_DIAMOND;
1035       break;
1036     case 1:
1037       x264_gtk->me_method = X264_ME_METHOD_HEXAGONAL;
1038       break;
1039     case 2:
1040       x264_gtk->me_method = X264_ME_METHOD_UNEVEN_MULTIHEXA;
1041       break;
1042     default:
1043       x264_gtk->me_method = X264_ME_METHOD_EXHAUSTIVE;
1044       break;
1045     }
1046   text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.motion_estimation.range));
1047   x264_gtk->range = (gint)g_ascii_strtoull (text, NULL, 10);
1048   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->more.motion_estimation.chroma_me)))
1049     x264_gtk->chroma_me = 1;
1050   else
1051     x264_gtk->chroma_me = 0;
1052   text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.motion_estimation.max_ref_frames));
1053   x264_gtk->max_ref_frames = (gint)g_ascii_strtoull (text, NULL, 10);
1054   if (x264_gtk->max_ref_frames <= 0)
1055     x264_gtk->max_ref_frames = 1;
1056   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->more.motion_estimation.mixed_refs)) &&
1057       (x264_gtk->max_ref_frames >= 2))
1058     x264_gtk->mixed_refs = 1;
1059   else
1060     x264_gtk->mixed_refs = 0;
1061   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->more.motion_estimation.fast_pskip)))
1062     x264_gtk->fast_pskip = 1;
1063   else
1064     x264_gtk->fast_pskip = 0;
1065   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->more.motion_estimation.dct_decimate)))
1066     x264_gtk->dct_decimate = 1;
1067   else
1068     x264_gtk->dct_decimate = 0;
1069
1070
1071   text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.misc.sample_ar_x));
1072   x264_gtk->sample_ar_x = (gint)g_ascii_strtoull (text, NULL, 10);
1073   text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.misc.sample_ar_y));
1074   x264_gtk->sample_ar_y = (gint)g_ascii_strtoull (text, NULL, 10);
1075   x264_gtk->threads = (gint)gtk_spin_button_get_value (GTK_SPIN_BUTTON (gconfig->more.misc.threads));
1076   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->more.misc.cabac)))
1077     x264_gtk->cabac = 1;
1078   else
1079     x264_gtk->cabac = 0;
1080   x264_gtk->trellis = gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->more.misc.trellis));
1081   text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.misc.noise_reduction));
1082   x264_gtk->noise_reduction = (gint)g_ascii_strtoull (text, NULL, 10);
1083   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->more.misc.df.deblocking_filter)))
1084     x264_gtk->deblocking_filter = 1;
1085   else
1086     x264_gtk->deblocking_filter = 0;
1087   x264_gtk->strength = (gint)gtk_range_get_value (GTK_RANGE (gconfig->more.misc.df.strength));
1088   x264_gtk->threshold = (gint)gtk_range_get_value (GTK_RANGE (gconfig->more.misc.df.threshold));
1089
1090   switch (gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->more.debug.log_level)))
1091     {
1092     case 0:
1093       x264_gtk->debug_method = X264_DEBUG_METHOD_NONE;
1094       break;
1095     case 1:
1096       x264_gtk->debug_method = X264_DEBUG_METHOD_ERROR;
1097       break;
1098     case 2:
1099       x264_gtk->debug_method = X264_DEBUG_METHOD_WARNING;
1100       break;
1101     case 3:
1102       x264_gtk->debug_method = X264_DEBUG_METHOD_INFO;
1103       break;
1104     default:
1105       x264_gtk->debug_method = X264_DEBUG_METHOD_DEBUG;
1106       break;
1107     }
1108   text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.debug.fourcc));
1109   memcpy (x264_gtk->fourcc, text, strlen (text) + 1);
1110
1111   /* cqm */
1112   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->cqm.radio_flat)))
1113     x264_gtk->cqm_preset = X264_CQM_PRESET_FLAT;
1114   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->cqm.radio_jvt)))
1115     x264_gtk->cqm_preset = X264_CQM_PRESET_JVT;
1116   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->cqm.radio_custom)))
1117     x264_gtk->cqm_preset = X264_CQM_PRESET_CUSTOM;
1118   text = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (gconfig->cqm.cqm_file));
1119   if (text && (text[0] != '\0'))
1120     memcpy (x264_gtk->cqm_file, text, strlen (text) + 1);
1121   for (i = 0; i < 16; i++) {
1122     text = gtk_entry_get_text (GTK_ENTRY (gconfig->cqm.cqm_4iy[i]));
1123     x264_gtk->cqm_4iy[i] = (gint)g_ascii_strtoull (text, NULL, 10);
1124     text = gtk_entry_get_text (GTK_ENTRY (gconfig->cqm.cqm_4ic[i]));
1125     x264_gtk->cqm_4ic[i] = (gint)g_ascii_strtoull (text, NULL, 10);
1126     text = gtk_entry_get_text (GTK_ENTRY (gconfig->cqm.cqm_4py[i]));
1127     x264_gtk->cqm_4py[i] = (gint)g_ascii_strtoull (text, NULL, 10);
1128     text = gtk_entry_get_text (GTK_ENTRY (gconfig->cqm.cqm_4pc[i]));
1129     x264_gtk->cqm_4pc[i] = (gint)g_ascii_strtoull (text, NULL, 10);
1130   }
1131   for (i = 0; i < 64; i++) {
1132     text = gtk_entry_get_text (GTK_ENTRY (gconfig->cqm.cqm_8iy[i]));
1133     x264_gtk->cqm_8iy[i] = (gint)g_ascii_strtoull (text, NULL, 10);
1134     text = gtk_entry_get_text (GTK_ENTRY (gconfig->cqm.cqm_8py[i]));
1135     x264_gtk->cqm_8py[i] = (gint)g_ascii_strtoull (text, NULL, 10);
1136   }
1137 }
1138
1139 gchar*
1140 x264_gtk_path(const char* more)
1141 {
1142 #ifdef _WIN32
1143   gchar szPath[MAX_PATH];
1144
1145   // "Documents and Settings\user" is CSIDL_PROFILE
1146   szPath[0] = 0;
1147
1148   SHGetSpecialFolderPath(NULL, szPath, CSIDL_APPDATA, FALSE);
1149   if (more)
1150     return g_build_filename(szPath, "x264", more, NULL);
1151   else
1152     return g_build_filename(szPath, "x264", NULL);
1153 #else
1154   if (more)
1155     return g_build_filename (g_get_home_dir (), ".x264", more, NULL);
1156   else
1157     return g_build_filename (g_get_home_dir (), ".x264", NULL);
1158 #endif
1159 }