E: tuukkat AT ee DOT oulu DOT fi
D: Visualization
+N: Vincent Torri
+E: Vincent DOT Torri AT iecn DOT u-nancy DOT fr
+D: GTK frontend
+
--- /dev/null
+
+include ../config.mak
+
+datadir=${prefix}/share/x264
+
+OBJECTS = x264_gtk_bitrate.o x264_gtk_rc.o x264_gtk_mb.o x264_gtk_more.o x264_gtk.o
+
+TEST_OBJECT = test.o
+ENCODE_OBJECT = x264_gtk_encode_encode.o x264_gtk_encode_status_window.o x264_gtk_encode_main_window.o x264_gtk_encode.o
+
+CC = gcc
+
+all: x264_gtk_encode test
+
+CPPFLAGS = `pkg-config --cflags gtk+-2.0 gthread-2.0 x264` -DX264_DATA_DIR=\"${datadir}\"
+CFLAGS = -O2 -Wall -W
+LDFLAGS += `pkg-config --libs gtk+-2.0 gthread-2.0 x264` -lpthread
+
+# Compilation rule
+%.o : %.c
+ @echo " C: $(@D)/$(<F)"
+ @$(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
+
+# Linking rule
+libx264gtk.a: $(OBJECTS)
+ @echo " L: $(@F)"
+ @ar rc libx264gtk.a $(OBJECTS)
+ @ranlib libx264gtk.a
+
+test: $(OBJECTS) $(TEST_OBJECT)
+ @echo " B: $(@F)"
+ @$(CC) -o test $(OBJECTS) $(TEST_OBJECT) $(LDFLAGS)
+
+x264_gtk_encode: $(OBJECTS) libx264gtk.a $(ENCODE_OBJECT)
+ @echo " B: $(@F)"
+ @$(CC) -o x264_gtk_encode $(OBJECTS) $(ENCODE_OBJECT) ../muxers.o ../matroska.o $(LDFLAGS)
+
+# Clean rule
+clean:
+ @rm -f *o test x264_gtk_encode libx264gtk.a
+
+# Install rule
+install: x264_gtk_encode
+ @echo " I: $(DESTDIR)$(includedir)/x264_gtk.h"
+ @install -m 644 x264_gtk.h $(DESTDIR)$(includedir)
+ @echo " I: $(DESTDIR)$(includedir)/x264_gtk_enum.h"
+ @install -m 644 x264_gtk_enum.h $(DESTDIR)$(includedir)
+ @echo " I: $(DESTDIR)$(libdir)/libx264gtk.a"
+ @install -m 644 libx264gtk.a $(DESTDIR)$(libdir)
+ @echo " I: $(DESTDIR)$(bindir)/x264_gtk_encode"
+ @install x264_gtk_encode $(DESTDIR)$(bindir)
+ @echo " D: $(DESTDIR)$(datadir)"
+ @install -d $(DESTDIR)$(datadir)
+ @echo " I: $(DESTDIR)$(datadir)/x264.png"
+ @install -m 644 x264.png $(DESTDIR)$(datadir)
+
+# Uninstall rule
+uninstall:
+ @echo " U: $(DESTDIR)$(includedir)/x264_gtk.h"
+ @rm -f $(DESTDIR)$(includedir)/x264_gtk.h
+ @echo " U: $(DESTDIR)$(includedir)/x264_gtk_enum.h"
+ @rm -f $(DESTDIR)$(includedir)/x264_gtk_enum.h
+ @echo " U: $(DESTDIR)$(libdir)/libx264gtk.a"
+ @rm -f $(DESTDIR)$(libdir)/libx264gtk.a
+ @echo " U: $(DESTDIR)$(bindir)/x264_gtk_encode"
+ @rm -f $(DESTDIR)$(bindir)/x264_gtk_encode
+ @echo " U: $(DESTDIR)$(datadir)"
+ @rm -rf $(DESTDIR)$(datadir)
+
+x264_gtk_bitrate.o: x264_gtk_bitrate.h x264_gtk_bitrate.c
+x264_gtk_rc.o: x264_gtk_rc.h x264_gtk_rc.c
+x264_gtk_mb.o: x264_gtk_mb.h x264_gtk_mb.c
+x264_gtk_more.o: x264_gtk_more.h x264_gtk_more.c
+gtk_x264.o: x264_gtk.h x264_gtk.c
+gtk_x264_encode_encode.o: x264_gtk.o x264_gtk_encode_encode.c
+gtk_x264_encode_status_window.o: x264_gtk.o x264_gtk_encode_status_window.c
+gtk_x264_encode_main_window.o: x264_gtk.o x264_gtk_encode_main_window.c
+gtk_x264_encode.o: x264_gtk.o x264_gtk_encode_encode.c x264_gtk_encode_status_window.c x264_gtk_encode_main_window.c x264_gtk_encode.c
+test.o: x264_gtk.o test.c
--- /dev/null
+#include <stdint.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+# define DECLARE_ALIGNED( type, var, n ) type var __attribute__((aligned(n)))
+#include "../common/common.h"
+#include "../x264.h"
+#include "x264_gtk.h"
+
+
+int
+main (int argc, char *argv[])
+{
+ GtkWidget *window;
+ X264_Gtk *x264_gtk;
+ x264_param_t *param;
+ x264_param_t param_default;
+ char *res;
+ char *res_default;
+
+ gtk_init (&argc, &argv);
+
+ window = x264_gtk_window_create (NULL);
+ x264_gtk_shutdown (window);
+
+ x264_gtk = x264_gtk_load ();
+ param = x264_gtk_param_get (x264_gtk);
+
+ /* do what you want with these data */
+ /* for example, displaying them and compare with default*/
+ res = x264_param2string (param, 0);
+ printf ("%s\n", res);
+
+ x264_param_default (¶m_default);
+ res_default = x264_param2string (¶m_default, 0);
+ printf ("\n%s\n", res_default);
+
+ if (strcmp (res, res_default) == 0)
+ printf ("\nSame result !\n");
+ else
+ printf ("\nDifferent from default values\n");
+
+ x264_free (res);
+ x264_free (res_default);
+
+ g_free (x264_gtk);
+ g_free (param);
+
+ gtk_main_quit ();
+
+ return 1;
+}
--- /dev/null
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <math.h>
+#if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__
+# include <inttypes.h>
+#else
+# include <stdint.h>
+#endif
+#ifdef _WIN32
+# include <unistd.h> /* for mkdir */
+#endif
+
+#include <x264.h>
+
+#include <gtk/gtk.h>
+
+#include "x264_gtk.h"
+#include "x264_gtk_private.h"
+#include "x264_gtk_enum.h"
+#include "x264_gtk_bitrate.h"
+#include "x264_gtk_rc.h"
+#include "x264_gtk_mb.h"
+#include "x264_gtk_more.h"
+
+
+#define CHECK_FLAG(a,flag) ((a) & (flag)) == (flag)
+#define round(a) ( ((a)<0.0) ? (gint)(floor((a) - 0.5)) : (gint)(floor((a) + 0.5)) )
+
+/* Callbacks */
+static void _dialog_run (GtkDialog *dialog,
+ gint response,
+ X264_Gui_Config *gconfig,
+ X264_Gtk *x264_gtk);
+
+
+/* x264 config management */
+static void _default_load (GtkButton *button, gpointer user_data);
+static void _current_get (X264_Gui_Config *gconfig, X264_Gtk *x264_gtk);
+static void _current_set (X264_Gui_Config *gconfig, X264_Gtk *x264_gtk);
+static void _default_set (X264_Gtk *x264_gtk);
+
+
+/* Result must be freed */
+x264_param_t *x264_gtk_param_get (X264_Gtk *x264_gtk)
+{
+ x264_param_t *param;
+
+ if (!x264_gtk)
+ return NULL;
+
+ param = (x264_param_t *)g_malloc (sizeof (x264_param_t));
+ if (!param)
+ return NULL;
+
+ x264_param_default (param);
+
+ /* bitrate */
+ if (x264_gtk->pass == X264_PASS_SINGLE_BITRATE)
+ param->rc.i_bitrate = x264_gtk->average_bitrate;
+ else
+ param->rc.i_bitrate = x264_gtk->target_bitrate;
+ param->rc.i_qp_constant = x264_gtk->quantizer;
+
+ /* FIXME: what to do about psz_stat_out ? */
+
+ /* rate control */
+ param->rc.f_ip_factor = 1.0 + (double)x264_gtk->keyframe_boost / 100.0;
+ param->rc.f_pb_factor = 1.0 + (double)x264_gtk->bframes_reduction / 100.0;
+ param->rc.f_qcompress = (double)x264_gtk->bitrate_variability / 100.0;
+
+ param->rc.i_qp_min = x264_gtk->min_qp;
+ param->rc.i_qp_max = x264_gtk->max_qp;
+ param->rc.i_qp_step = x264_gtk->max_qp_step;
+
+ param->i_scenecut_threshold = x264_gtk->scene_cut_threshold;
+ param->i_keyint_min = x264_gtk->min_idr_frame_interval;
+ param->i_keyint_max = x264_gtk->max_idr_frame_interval;
+
+ /* mb */
+ param->analyse.b_transform_8x8 = x264_gtk->transform_8x8;
+ param->analyse.inter = 0;
+ if (x264_gtk->pframe_search_8)
+ param->analyse.inter |= X264_ANALYSE_PSUB16x16;
+ if (x264_gtk->bframe_search_8)
+ param->analyse.inter |= X264_ANALYSE_BSUB16x16;
+ if (x264_gtk->pframe_search_4)
+ param->analyse.inter |= X264_ANALYSE_PSUB8x8;
+ if (x264_gtk->inter_search_8)
+ param->analyse.inter |= X264_ANALYSE_I8x8;
+ if (x264_gtk->inter_search_4)
+ param->analyse.inter |= X264_ANALYSE_I4x4;
+
+ param->i_bframe = x264_gtk->use_as_reference;
+ param->analyse.b_bidir_me = x264_gtk->bidir_me;
+ param->b_bframe_adaptive = x264_gtk->adaptive;
+ if ((x264_gtk->use_as_reference > 1) && x264_gtk->weighted_biprediction)
+ param->analyse.b_weighted_bipred = 1;
+ else
+ param->analyse.b_weighted_bipred = 0;
+ /* not used: */
+ /* x264_gtk->max_consecutive; */
+ param->i_bframe_bias = x264_gtk->bias;
+ param->analyse.i_direct_mv_pred = x264_gtk->direct_mode;
+
+ /* more */
+ param->analyse.i_subpel_refine = x264_gtk->partition_decision + 1;
+ param->analyse.b_bframe_rdo = x264_gtk->bframe_rdo;
+ param->analyse.i_me_method = x264_gtk->me_method;
+ param->analyse.i_me_range = x264_gtk->range;
+ param->analyse.b_chroma_me = x264_gtk->chroma_me;
+ param->analyse.i_trellis = x264_gtk->trellis;
+ param->analyse.i_noise_reduction = x264_gtk->noise_reduction;
+ param->i_frame_reference = x264_gtk->max_ref_frames;
+ param->analyse.b_mixed_references = x264_gtk->mixed_refs;
+
+ param->vui.i_sar_width = x264_gtk->sample_ar_x;
+ param->vui.i_sar_height = x264_gtk->sample_ar_y;
+ param->i_threads = x264_gtk->threads;
+ param->b_cabac = x264_gtk->cabac;
+ param->b_deblocking_filter = x264_gtk->deblocking_filter;
+ param->i_deblocking_filter_alphac0 = x264_gtk->strength;
+ param->i_deblocking_filter_beta = x264_gtk->threshold;
+
+ param->i_log_level = x264_gtk->debug_method - 1;
+
+ return param;
+}
+
+/* Result must be freed */
+X264_Gtk *
+x264_gtk_load (void)
+{
+ X264_Gtk *x264_gtk;
+ GIOChannel *file;
+ GError *error = NULL;
+ gchar *filename;
+
+ x264_gtk = (X264_Gtk *)g_malloc0 (sizeof (X264_Gtk));
+ if (!x264_gtk)
+ return NULL;
+
+ filename = g_build_filename (g_get_home_dir (),
+ ".x264",
+ "/x264.cfg",
+ NULL);
+ file = g_io_channel_new_file (filename, "r", &error);
+ if (error)
+ {
+ g_print ("x264.cfg: %s\n", error->message);
+ g_print ("Loading default configuration\n");
+ _default_set (x264_gtk);
+ }
+ else
+ {
+ GIOStatus status;
+ gchar *data = NULL;
+ gsize length;
+
+ g_print ("Loading configuration from %s\n", filename);
+ g_io_channel_set_encoding (file, NULL, NULL);
+ status = g_io_channel_read_to_end (file, &data, &length, &error);
+ if ((status == G_IO_STATUS_NORMAL) &&
+ (length == sizeof (X264_Gtk)))
+ {
+ memcpy (x264_gtk, data, length);
+ }
+ g_io_channel_shutdown (file, TRUE, NULL);
+ g_io_channel_unref (file);
+ }
+ g_free (filename);
+
+ return x264_gtk;
+}
+
+GtkWidget *
+x264_gtk_window_create (GtkWidget *parent)
+{
+ GtkWidget *win_x264_gtk;
+ GtkWidget *notebook;
+ GtkWidget *page;
+ GtkWidget *button;
+ GtkWidget *label;
+ X264_Gui_Config *gconfig;
+ X264_Gtk *x264_gtk;
+ gint result;
+ GtkDialogFlags flags = 0;
+
+ gconfig = (X264_Gui_Config *)g_malloc (sizeof (X264_Gui_Config));
+ if (!gconfig)
+ return NULL;
+
+ x264_gtk = x264_gtk_load ();
+
+ if (parent)
+ flags = GTK_DIALOG_MODAL |GTK_DIALOG_DESTROY_WITH_PARENT;
+ win_x264_gtk = gtk_dialog_new_with_buttons ("X264 Configuration",
+ GTK_WINDOW (parent),
+ flags,
+ NULL);
+
+ button = gtk_button_new_with_label ("Default");
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (win_x264_gtk)->action_area), button, FALSE, TRUE, 6);
+ g_signal_connect (G_OBJECT (button),
+ "clicked",
+ G_CALLBACK (_default_load),
+ gconfig);
+ gtk_widget_show (button);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (win_x264_gtk),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+
+ g_object_set_data (G_OBJECT (win_x264_gtk), "x264-gui-config", gconfig);
+ g_object_set_data (G_OBJECT (win_x264_gtk), "x264-config", x264_gtk);
+ gtk_window_set_resizable (GTK_WINDOW (win_x264_gtk), FALSE);
+
+ notebook = gtk_notebook_new ();
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (win_x264_gtk)->vbox), notebook);
+ gtk_widget_show (notebook);
+
+ label = gtk_label_new ("Bitrate");
+ gtk_widget_show (label);
+
+ page = _bitrate_page (gconfig);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
+ gtk_widget_show (page);
+
+ label = gtk_label_new ("Rate Control");
+ gtk_widget_show (label);
+
+ page = _rate_control_page (gconfig);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
+ gtk_widget_show (page);
+
+ label = gtk_label_new ("MB & Frames");
+ gtk_widget_show (label);
+
+ page = _mb_page (gconfig);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
+ gtk_widget_show (page);
+
+ label = gtk_label_new ("More...");
+ gtk_widget_show (label);
+
+ page = _more_page (gconfig);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
+ gtk_widget_show (page);
+
+ _current_set (gconfig, x264_gtk);
+
+ result = gtk_dialog_run (GTK_DIALOG (win_x264_gtk));
+ _dialog_run (GTK_DIALOG (win_x264_gtk), result, gconfig, x264_gtk);
+
+ return win_x264_gtk;
+}
+
+void
+x264_gtk_shutdown (GtkWidget *dialog)
+{
+ X264_Gui_Config *gconfig;
+
+ gconfig = g_object_get_data (G_OBJECT (dialog), "x264-gui-config");
+ gtk_widget_destroy (dialog);
+ if (gconfig)
+ g_free (gconfig);
+}
+
+
+/* Notebook pages */
+
+/* Callbacks */
+
+static void
+_dialog_run (GtkDialog *dialog __UNUSED__,
+ gint response,
+ X264_Gui_Config *gconfig,
+ X264_Gtk *x264_gtk)
+{
+ if (response == GTK_RESPONSE_OK)
+ {
+ GIOChannel *file;
+ gchar *filename;
+ gchar *dir;
+ gsize length;
+ gint res;
+#ifndef _WIN32
+ mode_t mode;
+#endif
+
+ dir = g_build_filename (g_get_home_dir (),
+ ".x264",
+ NULL);
+#ifdef _WIN32
+ res = mkdir (dir);
+#else
+ mode =
+ S_IRUSR | S_IXUSR | S_IWUSR |
+ S_IRGRP | S_IXGRP | S_IWGRP |
+ S_IROTH | S_IXOTH | S_IWOTH;
+ res = mkdir (dir, mode);
+#endif /* _WIN32 */
+ if (res != 0 && errno != EEXIST)
+ {
+ g_free (dir);
+
+ return;
+ }
+ filename = g_build_filename (g_get_home_dir (),
+ ".x264",
+ "x264.cfg",
+ NULL);
+ g_print ("Writing configuration to %s\n", filename);
+ file = g_io_channel_new_file (filename,
+ "w+", NULL);
+ if (file)
+ {
+ _current_get (gconfig, x264_gtk);
+ g_io_channel_set_encoding (file, NULL, NULL);
+ g_io_channel_write_chars (file, (const gchar *)x264_gtk,
+ sizeof (X264_Gtk), &length, NULL);
+ g_io_channel_unref (file);
+ }
+ g_free (filename);
+ g_free (dir);
+ }
+}
+
+/* x264 config management */
+static void
+_default_load (GtkButton *button __UNUSED__, gpointer user_data)
+{
+ X264_Gui_Config *config;
+ x264_param_t param;
+ gchar buf[64];
+
+ if (!user_data)
+ return;
+
+ config = (X264_Gui_Config *)user_data;
+
+ x264_param_default (¶m);
+
+ /* bitrate */
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->bitrate.pass), 1);
+ g_print ("bitrate %d\n", param.rc.i_bitrate);
+ g_snprintf (buf, 64, "%d", param.rc.i_bitrate);
+ gtk_entry_set_text (GTK_ENTRY (config->bitrate.w_average_bitrate), buf);
+ gtk_entry_set_text (GTK_ENTRY (config->bitrate.w_target_bitrate), buf);
+ gtk_range_set_range (GTK_RANGE (config->bitrate.w_quantizer),
+ (gdouble)param.rc.i_qp_min,
+ (gdouble)param.rc.i_qp_max);
+ gtk_range_set_value (GTK_RANGE (config->bitrate.w_quantizer),
+ (gdouble)param.rc.i_qp_constant);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->bitrate.update_statfile), FALSE);
+ gtk_entry_set_text (GTK_ENTRY (config->bitrate.statsfile_name), "x264.stats");
+ gtk_widget_set_sensitive (config->bitrate.statsfile_name, FALSE);
+
+ /* rate control */
+ g_snprintf (buf, 64, "%d", round((param.rc.f_ip_factor - 1) * 100));
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.keyframe_boost), buf);
+ g_snprintf (buf, 64, "%d", round((param.rc.f_pb_factor - 1) * 100));
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.bframes_reduction), buf);
+ g_snprintf (buf, 64, "%d", (gint)(param.rc.f_qcompress * 100));
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.bitrate_variability), buf);
+
+ g_snprintf (buf, 64, "%d", param.rc.i_qp_min);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.min_qp), buf);
+ g_snprintf (buf, 64, "%d", param.rc.i_qp_max);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.max_qp), buf);
+ g_snprintf (buf, 64, "%d", param.rc.i_qp_step);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.max_qp_step), buf);
+
+ g_snprintf (buf, 64, "%d", param.i_scenecut_threshold);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.scene_cut_threshold), buf);
+ g_snprintf (buf, 64, "%d", param.i_keyint_min);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.min_idr_frame_interval), buf);
+ g_snprintf (buf, 64, "%d", param.i_keyint_max);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.max_idr_frame_interval), buf);
+
+ /* mb */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.transform_8x8), param.analyse.b_transform_8x8);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_8), CHECK_FLAG(param.analyse.inter, X264_ANALYSE_PSUB16x16));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.bframe_search_8), CHECK_FLAG(param.analyse.inter, X264_ANALYSE_BSUB16x16));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_4), CHECK_FLAG(param.analyse.inter, X264_ANALYSE_PSUB8x8));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_8), CHECK_FLAG(param.analyse.inter, X264_ANALYSE_I8x8));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_4), CHECK_FLAG(param.analyse.inter, X264_ANALYSE_I4x4));
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.use_as_reference), param.i_bframe);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.adaptive), param.b_bframe_adaptive);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.weighted_biprediction), param.analyse.b_weighted_bipred);
+ g_snprintf (buf, 64, "%d", param.b_bframe_adaptive);
+ gtk_entry_set_text (GTK_ENTRY (config->mb.bframes.max_consecutive), buf);
+ gtk_range_set_value (GTK_RANGE (config->mb.bframes.bias), (gdouble)param.i_bframe_bias);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->mb.bframes.direct_mode), param.analyse.i_direct_mv_pred);
+
+ /* more */
+ if (param.analyse.b_bframe_rdo)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision), X264_PD_6b);
+ else
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision), param.analyse.i_subpel_refine - 1);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.method), param.analyse.i_me_method);
+ g_snprintf (buf, 64, "%d", param.analyse.i_me_range);
+ gtk_entry_set_text (GTK_ENTRY (config->more.motion_estimation.range), buf);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.chroma_me), param.analyse.b_chroma_me);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.mixed_refs), param.analyse.b_mixed_references);
+ g_snprintf (buf, 64, "%d", param.i_frame_reference);
+ gtk_entry_set_text (GTK_ENTRY (config->more.motion_estimation.max_ref_frames), buf);
+
+ g_snprintf (buf, 64, "%d", param.vui.i_sar_width);
+ gtk_entry_set_text (GTK_ENTRY (config->more.misc.sample_ar_x), buf);
+ g_snprintf (buf, 64, "%d", param.vui.i_sar_height);
+ gtk_entry_set_text (GTK_ENTRY (config->more.misc.sample_ar_y), buf);
+ g_snprintf (buf, 64, "%d", param.i_threads);
+ gtk_entry_set_text (GTK_ENTRY (config->more.misc.threads), buf);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.cabac), param.b_cabac);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.misc.trellis), param.analyse.i_trellis);
+ g_snprintf (buf, 64, "%d", param.analyse.i_noise_reduction);
+ gtk_entry_set_text (GTK_ENTRY (config->more.misc.noise_reduction), buf);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.df.deblocking_filter), param.b_deblocking_filter);
+ gtk_range_set_value (GTK_RANGE (config->more.misc.df.strength), (gdouble)param.i_deblocking_filter_alphac0);
+ gtk_range_set_value (GTK_RANGE (config->more.misc.df.threshold), (gdouble)param.i_deblocking_filter_beta);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.debug.log_level), 1);
+ gtk_entry_set_text (GTK_ENTRY (config->more.debug.fourcc), "H264");
+}
+
+static void
+_default_set (X264_Gtk *x264_gtk)
+{
+ x264_param_t param;
+ gchar *text;
+
+ x264_param_default (¶m);
+
+ /* bitrate */
+ x264_gtk->pass = X264_PASS_SINGLE_QUANTIZER;
+ x264_gtk->average_bitrate = param.rc.i_bitrate;
+ x264_gtk->target_bitrate = param.rc.i_bitrate;
+ x264_gtk->quantizer = param.rc.i_qp_constant;
+ x264_gtk->update_statfile = 0;
+ text = "x264.stats";
+ memcpy (x264_gtk->statsfile_name, text, strlen (text) + 1);
+
+ /* rate control */
+ x264_gtk->keyframe_boost = round((param.rc.f_ip_factor - 1) * 100);
+ x264_gtk->bframes_reduction = round((param.rc.f_pb_factor - 1) * 100);
+ x264_gtk->bitrate_variability = round(param.rc.f_qcompress * 100);
+
+ x264_gtk->min_qp = param.rc.i_qp_min;
+ x264_gtk->max_qp = param.rc.i_qp_max;
+ x264_gtk->max_qp_step = param.rc.i_qp_step;
+
+ x264_gtk->scene_cut_threshold = param.i_scenecut_threshold;
+ x264_gtk->min_idr_frame_interval = param.i_keyint_min;
+ x264_gtk->max_idr_frame_interval = param.i_keyint_max;
+ x264_gtk->direct_mode = param.analyse.i_direct_mv_pred;
+
+ /* mb */
+ x264_gtk->transform_8x8 = param.analyse.b_transform_8x8;
+ x264_gtk->max_ref_frames = param.i_frame_reference;
+ x264_gtk->mixed_refs = param.analyse.b_mixed_references;
+
+ if (CHECK_FLAG(param.analyse.inter, X264_ANALYSE_PSUB16x16))
+ x264_gtk->pframe_search_8 = 1;
+ else
+ x264_gtk->pframe_search_8 = 0;
+ if (CHECK_FLAG(param.analyse.inter, X264_ANALYSE_BSUB16x16))
+ x264_gtk->bframe_search_8 = 1;
+ else
+ x264_gtk->bframe_search_8 = 0;
+ if (CHECK_FLAG(param.analyse.inter, X264_ANALYSE_PSUB8x8))
+ x264_gtk->pframe_search_4 = 1;
+ else
+ x264_gtk->pframe_search_4 = 0;
+ x264_gtk->inter_search_8 = CHECK_FLAG(param.analyse.inter, X264_ANALYSE_I8x8);
+ x264_gtk->inter_search_4 = CHECK_FLAG(param.analyse.inter, X264_ANALYSE_I4x4);
+
+ x264_gtk->use_as_reference = param.i_bframe;
+ x264_gtk->adaptive = param.b_bframe_adaptive;
+ x264_gtk->weighted_biprediction = param.analyse.b_weighted_bipred;
+ x264_gtk->max_consecutive = 0; /* not used */
+ x264_gtk->bias = param.i_bframe_bias;
+
+ /* more */
+ x264_gtk->bframe_rdo = param.analyse.b_bframe_rdo;
+ x264_gtk->partition_decision = param.analyse.i_subpel_refine - 1;
+ x264_gtk->me_method = param.analyse.i_me_method;
+ x264_gtk->range = param.analyse.i_me_range;
+ x264_gtk->chroma_me = param.analyse.b_chroma_me;
+
+ x264_gtk->sample_ar_x = param.vui.i_sar_width;
+ x264_gtk->sample_ar_y = param.vui.i_sar_height;
+ x264_gtk->threads = param.i_threads;
+ x264_gtk->cabac = param.b_cabac;
+ x264_gtk->trellis = param.analyse.i_trellis;
+ x264_gtk->noise_reduction = param.analyse.i_noise_reduction;
+ x264_gtk->deblocking_filter = param.b_deblocking_filter;
+ x264_gtk->strength = param.i_deblocking_filter_alphac0;
+ x264_gtk->threshold = param.i_deblocking_filter_beta;
+
+ x264_gtk->debug_method = X264_DEBUG_METHOD_ERROR;
+ text = "H264";
+ memcpy (x264_gtk->fourcc, text, strlen (text) + 1);
+}
+
+static void
+_current_set (X264_Gui_Config *config, X264_Gtk *x264_gtk)
+{
+ gchar buf[4096];
+
+ if (!config)
+ return;
+
+ /* bitrate */
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->bitrate.pass), x264_gtk->pass);
+ g_snprintf (buf, 5, "%d", x264_gtk->average_bitrate);
+ gtk_entry_set_text (GTK_ENTRY (config->bitrate.w_average_bitrate), buf);
+ gtk_range_set_value (GTK_RANGE (config->bitrate.w_quantizer), x264_gtk->quantizer);
+ g_snprintf (buf, 5, "%d", x264_gtk->target_bitrate);
+ gtk_entry_set_text (GTK_ENTRY (config->bitrate.w_target_bitrate), buf);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->bitrate.update_statfile), x264_gtk->update_statfile);
+ gtk_entry_set_text (GTK_ENTRY (config->bitrate.statsfile_name), x264_gtk->statsfile_name);
+ if (x264_gtk->update_statfile)
+ gtk_widget_set_sensitive (config->bitrate.statsfile_name, TRUE);
+ else
+ gtk_widget_set_sensitive (config->bitrate.statsfile_name, FALSE);
+
+ /* rate control */
+ g_snprintf (buf, 5, "%d", x264_gtk->keyframe_boost);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.keyframe_boost), buf);
+ g_snprintf (buf, 5, "%d", x264_gtk->bframes_reduction);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.bframes_reduction), buf);
+ g_snprintf (buf, 5, "%d", x264_gtk->bitrate_variability);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.bitrate.bitrate_variability), buf);
+
+ g_snprintf (buf, 5, "%d", x264_gtk->min_qp);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.min_qp), buf);
+ g_snprintf (buf, 5, "%d", x264_gtk->max_qp);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.max_qp), buf);
+ g_snprintf (buf, 5, "%d", x264_gtk->max_qp_step);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.quantization_limits.max_qp_step), buf);
+
+ g_snprintf (buf, 5, "%d", x264_gtk->scene_cut_threshold);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.scene_cut_threshold), buf);
+ g_snprintf (buf, 5, "%d", x264_gtk->min_idr_frame_interval);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.min_idr_frame_interval), buf);
+ g_snprintf (buf, 5, "%d", x264_gtk->max_idr_frame_interval);
+ gtk_entry_set_text (GTK_ENTRY (config->rate_control.scene_cuts.max_idr_frame_interval), buf);
+
+ /* mb */
+ if (x264_gtk->transform_8x8)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.transform_8x8), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.transform_8x8), FALSE);
+ if (x264_gtk->pframe_search_8)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_8), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_8), FALSE);
+ if (x264_gtk->bframe_search_8)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.bframe_search_8), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.bframe_search_8), FALSE);
+ if (x264_gtk->pframe_search_4)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_4), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.pframe_search_4), FALSE);
+ if (x264_gtk->inter_search_8)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_8), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_8), FALSE);
+ if (x264_gtk->inter_search_4)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_4), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.partitions.inter_search_4), FALSE);
+
+ if (x264_gtk->use_as_reference)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.use_as_reference), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.use_as_reference), FALSE);
+ if (x264_gtk->bidir_me)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.bidir_me), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.bidir_me), FALSE);
+ if (x264_gtk->adaptive)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.adaptive), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.adaptive), FALSE);
+ if (x264_gtk->weighted_biprediction)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.weighted_biprediction), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->mb.bframes.weighted_biprediction), FALSE);
+ g_snprintf (buf, 5, "%d", x264_gtk->max_consecutive);
+ gtk_entry_set_text (GTK_ENTRY (config->mb.bframes.max_consecutive), buf);
+ gtk_range_set_value (GTK_RANGE (config->mb.bframes.bias), (gdouble)x264_gtk->bias);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->mb.bframes.direct_mode), x264_gtk->direct_mode);
+
+ /* more */
+ if (x264_gtk->bframe_rdo)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision), X264_PD_6b);
+ else
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision), x264_gtk->partition_decision);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.motion_estimation.method), x264_gtk->me_method);
+ g_snprintf (buf, 5, "%d", x264_gtk->range);
+ gtk_entry_set_text (GTK_ENTRY (config->more.motion_estimation.range), buf);
+ if (x264_gtk->chroma_me)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.chroma_me), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.chroma_me), FALSE);
+ g_snprintf (buf, 5, "%d", x264_gtk->max_ref_frames);
+ gtk_entry_set_text (GTK_ENTRY (config->more.motion_estimation.max_ref_frames), buf);
+ if (x264_gtk->mixed_refs)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.mixed_refs), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.motion_estimation.mixed_refs), FALSE);
+
+ g_snprintf (buf, 5, "%d", x264_gtk->sample_ar_x);
+ gtk_entry_set_text (GTK_ENTRY (config->more.misc.sample_ar_x), buf);
+ g_snprintf (buf, 5, "%d", x264_gtk->sample_ar_y);
+ gtk_entry_set_text (GTK_ENTRY (config->more.misc.sample_ar_y), buf);
+ g_snprintf (buf, 5, "%d", x264_gtk->threads);
+ gtk_entry_set_text (GTK_ENTRY (config->more.misc.threads), buf);
+ if (x264_gtk->cabac)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.cabac), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.cabac), FALSE);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.misc.trellis), x264_gtk->trellis);
+ g_snprintf (buf, 64, "%d", x264_gtk->noise_reduction);
+ gtk_entry_set_text (GTK_ENTRY (config->more.misc.noise_reduction), buf);
+ if (x264_gtk->deblocking_filter)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.df.deblocking_filter), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (config->more.misc.df.deblocking_filter), FALSE);
+ gtk_range_set_value (GTK_RANGE (config->more.misc.df.strength), (gdouble)x264_gtk->strength);
+ gtk_range_set_value (GTK_RANGE (config->more.misc.df.threshold), (gdouble)x264_gtk->threshold);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (config->more.debug.log_level), x264_gtk->debug_method);
+ gtk_entry_set_text (GTK_ENTRY (config->more.debug.fourcc),
+ x264_gtk->fourcc);
+}
+
+static void
+_current_get (X264_Gui_Config *gconfig, X264_Gtk *x264_gtk)
+{
+ const gchar *text;
+
+ if (!gconfig)
+ return;
+
+ if (!x264_gtk)
+ g_print ("problem...\n");
+
+ /* bitrate */
+ switch (gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->bitrate.pass)))
+ {
+ case 0:
+ x264_gtk->pass = X264_PASS_SINGLE_BITRATE;
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->bitrate.w_average_bitrate));
+ x264_gtk->average_bitrate = (gint)g_ascii_strtoull (text, NULL, 10);
+ break;
+ case 1:
+ x264_gtk->pass = X264_PASS_SINGLE_QUANTIZER;
+ x264_gtk->quantizer = (gint)gtk_range_get_value (GTK_RANGE (gconfig->bitrate.w_quantizer));
+ break;
+ case 2:
+ x264_gtk->pass = X264_PASS_MULTIPASS_1ST;
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->bitrate.w_target_bitrate));
+ x264_gtk->target_bitrate = (gint)g_ascii_strtoull (text, NULL, 10);
+ break;
+ case 3:
+ x264_gtk->pass = X264_PASS_MULTIPASS_1ST_FAST;
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->bitrate.w_target_bitrate));
+ x264_gtk->target_bitrate = (gint)g_ascii_strtoull (text, NULL, 10);
+ break;
+ case 4:
+ default:
+ x264_gtk->pass = X264_PASS_MULTIPASS_NTH;
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->bitrate.w_target_bitrate));
+ x264_gtk->target_bitrate = (gint)g_ascii_strtoull (text, NULL, 10);
+ break;
+ }
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->bitrate.update_statfile)))
+ x264_gtk->update_statfile = 1;
+ else
+ x264_gtk->update_statfile = 0;
+
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->bitrate.statsfile_name));
+ memcpy (x264_gtk->statsfile_name,
+ text,
+ strlen(text) + 1);
+
+ /* rate control */
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.bitrate.keyframe_boost));
+ x264_gtk->keyframe_boost = (gint)g_ascii_strtoull (text, NULL, 10);
+
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.bitrate.bframes_reduction));
+ x264_gtk->bframes_reduction = (gint)g_ascii_strtoull (text, NULL, 10);
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.bitrate.bitrate_variability));
+ x264_gtk->bitrate_variability = (gint)g_ascii_strtoull (text, NULL, 10);
+
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.quantization_limits.min_qp));
+ x264_gtk->min_qp = (gint)g_ascii_strtoull (text, NULL, 10);
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.quantization_limits.max_qp));
+ x264_gtk->max_qp = (gint)g_ascii_strtoull (text, NULL, 10);
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.quantization_limits.max_qp_step));
+ x264_gtk->max_qp_step = (gint)g_ascii_strtoull (text, NULL, 10);
+
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.scene_cuts.scene_cut_threshold));
+ x264_gtk->scene_cut_threshold = (gint)g_ascii_strtoull (text, NULL, 10);
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.scene_cuts.min_idr_frame_interval));
+ x264_gtk->min_idr_frame_interval = (gint)g_ascii_strtoull (text, NULL, 10);
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->rate_control.scene_cuts.max_idr_frame_interval));
+ x264_gtk->max_idr_frame_interval = (gint)g_ascii_strtoull (text, NULL, 10);
+
+ /* mb */
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.transform_8x8)))
+ x264_gtk->transform_8x8 = 1;
+ else
+ x264_gtk->transform_8x8 = 0;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.pframe_search_8)))
+ x264_gtk->pframe_search_8 = 1;
+ else
+ x264_gtk->pframe_search_8 = 0;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.bframe_search_8)))
+ x264_gtk->bframe_search_8 = 1;
+ else
+ x264_gtk->bframe_search_8 = 0;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.pframe_search_4)))
+ x264_gtk->pframe_search_4 = 1;
+ else
+ x264_gtk->pframe_search_4 = 0;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.inter_search_8)))
+ x264_gtk->inter_search_8 = 1;
+ else
+ x264_gtk->inter_search_8 = 0;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.partitions.inter_search_4)))
+ x264_gtk->inter_search_4 = 1;
+ else
+ x264_gtk->inter_search_4 = 0;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.bframes.use_as_reference)))
+ x264_gtk->use_as_reference = 1;
+ else
+ x264_gtk->use_as_reference = 0;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.bframes.bidir_me)))
+ x264_gtk->bidir_me = 1;
+ else
+ x264_gtk->bidir_me = 0;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.bframes.adaptive)))
+ x264_gtk->adaptive = 1;
+ else
+ x264_gtk->adaptive = 0;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->mb.bframes.weighted_biprediction)))
+ x264_gtk->weighted_biprediction = 1;
+ else
+ x264_gtk->weighted_biprediction = 0;
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->mb.bframes.max_consecutive));
+ x264_gtk->max_consecutive = (gint)g_ascii_strtoull (text, NULL, 10);
+ x264_gtk->bias = (gint)gtk_range_get_value (GTK_RANGE (gconfig->mb.bframes.bias));
+
+ switch (gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->mb.bframes.direct_mode)))
+ {
+ case 0:
+ x264_gtk->direct_mode = X264_NONE;
+ case 1:
+ x264_gtk->direct_mode = X264_SPATIAL;
+ break;
+ default:
+ x264_gtk->direct_mode = X264_TEMPORAL;
+ break;
+ }
+
+ /* more */
+ switch (gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->more.motion_estimation.partition_decision)))
+ {
+ case 0:
+ x264_gtk->partition_decision = X264_PD_1;
+ break;
+ case 1:
+ x264_gtk->partition_decision = X264_PD_2;
+ break;
+ case 2:
+ x264_gtk->partition_decision = X264_PD_3;
+ break;
+ case 3:
+ x264_gtk->partition_decision = X264_PD_4;
+ break;
+ case 4:
+ x264_gtk->partition_decision = X264_PD_5;
+ break;
+ case 5:
+ x264_gtk->partition_decision = X264_PD_6;
+ break;
+ default:
+ x264_gtk->partition_decision = X264_PD_6;
+ x264_gtk->bframe_rdo = 1;
+ break;
+ }
+ switch (gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->more.motion_estimation.method)))
+ {
+ case 0:
+ x264_gtk->me_method = X264_ME_METHOD_DIAMOND;
+ break;
+ case 1:
+ x264_gtk->me_method = X264_ME_METHOD_HEXAGONAL;
+ break;
+ case 2:
+ x264_gtk->me_method = X264_ME_METHOD_UNEVEN_MULTIHEXA;
+ break;
+ default:
+ x264_gtk->me_method = X264_ME_METHOD_EXHAUSTIVE;
+ break;
+ }
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.motion_estimation.range));
+ x264_gtk->range = (gint)g_ascii_strtoull (text, NULL, 10);
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->more.motion_estimation.chroma_me)))
+ x264_gtk->chroma_me = 1;
+ else
+ x264_gtk->chroma_me = 0;
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.motion_estimation.max_ref_frames));
+ x264_gtk->max_ref_frames = (gint)g_ascii_strtoull (text, NULL, 10);
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->more.motion_estimation.mixed_refs)))
+ x264_gtk->mixed_refs = 1;
+ else
+ x264_gtk->mixed_refs = 0;
+
+
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.misc.sample_ar_x));
+ x264_gtk->sample_ar_x = (gint)g_ascii_strtoull (text, NULL, 10);
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.misc.sample_ar_y));
+ x264_gtk->sample_ar_y = (gint)g_ascii_strtoull (text, NULL, 10);
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.misc.threads));
+ x264_gtk->threads = (gint)g_ascii_strtoull (text, NULL, 10);
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->more.misc.cabac)))
+ x264_gtk->cabac = 1;
+ else
+ x264_gtk->cabac = 0;
+ x264_gtk->trellis = gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->more.misc.trellis));
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.misc.noise_reduction));
+ x264_gtk->noise_reduction = (gint)g_ascii_strtoull (text, NULL, 10);
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gconfig->more.misc.df.deblocking_filter)))
+ x264_gtk->deblocking_filter = 1;
+ else
+ x264_gtk->deblocking_filter = 0;
+ x264_gtk->strength = (gint)gtk_range_get_value (GTK_RANGE (gconfig->more.misc.df.strength));
+ x264_gtk->threshold = (gint)gtk_range_get_value (GTK_RANGE (gconfig->more.misc.df.threshold));
+
+ switch (gtk_combo_box_get_active (GTK_COMBO_BOX (gconfig->more.debug.log_level)))
+ {
+ case 0:
+ x264_gtk->debug_method = X264_DEBUG_METHOD_NONE;
+ break;
+ case 1:
+ x264_gtk->debug_method = X264_DEBUG_METHOD_ERROR;
+ break;
+ case 2:
+ x264_gtk->debug_method = X264_DEBUG_METHOD_WARNING;
+ break;
+ case 3:
+ x264_gtk->debug_method = X264_DEBUG_METHOD_INFO;
+ break;
+ default:
+ x264_gtk->debug_method = X264_DEBUG_METHOD_DEBUG;
+ break;
+ }
+ text = gtk_entry_get_text (GTK_ENTRY (gconfig->more.debug.fourcc));
+ memcpy (x264_gtk->fourcc, text, strlen (text) + 1);
+}
--- /dev/null
+#ifndef __X264_GTK_H__
+#define __X264_GTK_H__
+
+
+#include "x264_gtk_enum.h"
+
+
+typedef struct X264_Gtk_ X264_Gtk;
+
+struct X264_Gtk_
+{
+ /* video properties */
+ gint width;
+ gint height;
+ gint csp;
+
+ /* bitrate */
+ X264_Pass pass;
+ gint average_bitrate;
+ gint target_bitrate;
+ gint quantizer;
+ gint desired_size;
+ gint statfile_length; /* length of the filename (as returned by strlen) */
+ gchar statsfile_name[4095+1];
+
+ /* rc */
+ gint keyframe_boost;
+ gint bframes_reduction;
+ gint bitrate_variability;
+
+ gint min_qp;
+ gint max_qp;
+ gint max_qp_step;
+
+ gint scene_cut_threshold;
+ gint min_idr_frame_interval;
+ gint max_idr_frame_interval;
+
+ /* mb */
+
+ gint max_consecutive;
+ gint bias;
+ X264_Direct_Mode direct_mode;
+
+ /* more */
+ X264_Partition_Decision partition_decision;
+ X264_Me_Method me_method;
+ gint range;
+ gint max_ref_frames;
+
+ gint sample_ar_x;
+ gint sample_ar_y;
+ gint threads;
+ guint trellis;
+ gint noise_reduction;
+
+ gint strength;
+ gint threshold;
+
+ X264_Debug_Method debug_method;
+ gchar fourcc[4+1];
+
+ /* bitrate */
+ guint update_statfile : 1;
+ /* mb - partitions */
+ guint transform_8x8 : 1;
+ guint pframe_search_8 : 1;
+ guint bframe_search_8 : 1;
+ guint pframe_search_4 : 1;
+ guint inter_search_8 : 1;
+ guint inter_search_4 : 1;
+ /* mb - bframes */
+ guint use_as_reference : 1;
+ guint bidir_me : 1;
+ guint adaptive : 1;
+ guint weighted_biprediction : 1;
+ /* more - me */
+ guint bframe_rdo : 1;
+ guint chroma_me : 1;
+ guint mixed_refs : 1;
+ /* more - misc */
+ guint cabac : 1;
+ /* more - misc - df */
+ guint deblocking_filter : 1;
+};
+
+x264_param_t *x264_gtk_param_get (X264_Gtk *x264_gtk);
+X264_Gtk *x264_gtk_load (void);
+GtkWidget *x264_gtk_window_create (GtkWidget *parent);
+void x264_gtk_shutdown (GtkWidget *dialog);
+
+
+#endif /* __X264_GTK_H__ */
--- /dev/null
+#if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__
+# include <inttypes.h>
+#else
+# include <stdint.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "../x264.h"
+#include "x264_gtk_private.h"
+#include "x264_gtk_enum.h"
+#include "x264_gtk_bitrate.h"
+
+
+/* Callbacks */
+static void _bitrate_pass (GtkComboBox *combo,
+ gpointer user_data);
+static void _bitrate_statfile (GtkToggleButton *button,
+ gpointer user_data);
+
+GtkWidget *
+_bitrate_page (X264_Gui_Config *gconfig)
+{
+ GtkWidget *vbox;
+ GtkWidget *frame;
+ GtkWidget *table;
+ GtkWidget *image;
+ GtkWidget *label;
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+
+ image = gtk_image_new_from_file (X264_DATA_DIR "/x264.png");
+ gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, TRUE, 6);
+ gtk_widget_show (image);
+
+ frame = gtk_frame_new ("Main settings");
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (2, 2, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Encoding type");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 0, 1);
+ gtk_widget_show (label);
+
+ gconfig->bitrate.pass = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (gconfig->bitrate.pass),
+ "Single Pass - Bitrate");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (gconfig->bitrate.pass),
+ "Single Pass - Quantizer");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (gconfig->bitrate.pass),
+ "Multipass - First Pass");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (gconfig->bitrate.pass),
+ "Multipass - First Pass (fast)");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (gconfig->bitrate.pass),
+ "Multipass - Nth Pass");
+ gtk_table_attach_defaults (GTK_TABLE (table), gconfig->bitrate.pass,
+ 1, 2, 0, 1);
+ g_signal_connect (G_OBJECT (gconfig->bitrate.pass),
+ "changed",
+ G_CALLBACK (_bitrate_pass),
+ gconfig);
+ gtk_widget_show (gconfig->bitrate.pass);
+
+ gconfig->bitrate.label = gtk_label_new ("Quantizer");
+ gtk_misc_set_alignment (GTK_MISC (gconfig->bitrate.label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), gconfig->bitrate.label,
+ 0, 1, 1, 2);
+ gtk_widget_show (gconfig->bitrate.label);
+
+ gconfig->bitrate.w_quantizer = gtk_hscale_new_with_range (0.0, 51.0, 1.0);
+ gtk_scale_set_digits (GTK_SCALE (gconfig->bitrate.w_quantizer), 0);
+ gtk_scale_set_value_pos (GTK_SCALE (gconfig->bitrate.w_quantizer), GTK_POS_RIGHT);
+ gtk_table_attach_defaults (GTK_TABLE (table), gconfig->bitrate.w_quantizer,
+ 1, 2, 1, 2);
+
+ gconfig->bitrate.w_average_bitrate = gtk_entry_new_with_max_length (4095);
+ gtk_table_attach_defaults (GTK_TABLE (table), gconfig->bitrate.w_average_bitrate,
+ 1, 2, 1, 2);
+
+ gconfig->bitrate.w_target_bitrate = gtk_entry_new_with_max_length (4095);
+ gtk_table_attach_defaults (GTK_TABLE (table), gconfig->bitrate.w_target_bitrate,
+ 1, 2, 1, 2);
+
+ frame = gtk_frame_new ("Statistic file");
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (2, 2, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ gconfig->bitrate.update_statfile = gtk_check_button_new_with_label ("Update Statfile");
+ g_signal_connect (G_OBJECT (gconfig->bitrate.update_statfile),
+ "toggled",
+ G_CALLBACK (_bitrate_statfile), gconfig);
+ gtk_table_attach_defaults (GTK_TABLE (table), gconfig->bitrate.update_statfile,
+ 0, 1, 0, 1);
+ gtk_widget_show (gconfig->bitrate.update_statfile);
+
+ label = gtk_label_new ("Statsfile name");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 1, 2);
+ gtk_widget_show (label);
+
+ gconfig->bitrate.statsfile_name = gtk_entry_new_with_max_length (4095);
+ gtk_table_attach_defaults (GTK_TABLE (table), gconfig->bitrate.statsfile_name,
+ 1, 2, 1, 2);
+ gtk_widget_show (gconfig->bitrate.statsfile_name);
+
+ return vbox;
+}
+
+/* Callbacks */
+static void
+_bitrate_pass (GtkComboBox *combo,
+ gpointer user_data)
+{
+ X264_Gui_Config *gconfig;
+
+ gconfig = (X264_Gui_Config *)user_data;
+
+ switch (gtk_combo_box_get_active (combo))
+ {
+ case X264_PASS_SINGLE_BITRATE:
+ gtk_label_set_text (GTK_LABEL (gconfig->bitrate.label), "Average bitrate");
+ if (!GTK_WIDGET_VISIBLE (gconfig->bitrate.w_average_bitrate)) {
+ gtk_widget_hide (gconfig->bitrate.w_quantizer);
+ gtk_widget_hide (gconfig->bitrate.w_target_bitrate);
+ gtk_widget_show (gconfig->bitrate.w_average_bitrate);
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gconfig->bitrate.update_statfile), FALSE);
+ break;
+ case X264_PASS_SINGLE_QUANTIZER:
+ gtk_label_set_text (GTK_LABEL (gconfig->bitrate.label), "Quantizer");
+ if (!GTK_WIDGET_VISIBLE (gconfig->bitrate.w_quantizer)) {
+ gtk_widget_hide (gconfig->bitrate.w_average_bitrate);
+ gtk_widget_hide (gconfig->bitrate.w_target_bitrate);
+ gtk_widget_show (gconfig->bitrate.w_quantizer);
+ }
+ break;
+ case X264_PASS_MULTIPASS_1ST:
+ case X264_PASS_MULTIPASS_1ST_FAST:
+ gtk_label_set_text (GTK_LABEL (gconfig->bitrate.label), "Target bitrate");
+ if (!GTK_WIDGET_VISIBLE (gconfig->bitrate.w_target_bitrate)) {
+ gtk_widget_hide (gconfig->bitrate.w_quantizer);
+ gtk_widget_hide (gconfig->bitrate.w_average_bitrate);
+ gtk_widget_show (gconfig->bitrate.w_target_bitrate);
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gconfig->bitrate.update_statfile), TRUE);
+ break;
+ case X264_PASS_MULTIPASS_NTH:
+ gtk_label_set_text (GTK_LABEL (gconfig->bitrate.label), "Target bitrate");
+ if (!GTK_WIDGET_VISIBLE (gconfig->bitrate.w_target_bitrate)) {
+ gtk_widget_hide (gconfig->bitrate.w_quantizer);
+ gtk_widget_hide (gconfig->bitrate.w_average_bitrate);
+ gtk_widget_show (gconfig->bitrate.w_target_bitrate);
+ }
+ break;
+ }
+}
+
+static void
+_bitrate_statfile (GtkToggleButton *button,
+ gpointer user_data)
+{
+ X264_Gui_Config *gconfig;
+
+ gconfig = (X264_Gui_Config *)user_data;
+
+ if (gtk_toggle_button_get_active (button))
+ gtk_widget_set_sensitive (gconfig->bitrate.statsfile_name, TRUE);
+ else
+ gtk_widget_set_sensitive (gconfig->bitrate.statsfile_name, FALSE);
+}
--- /dev/null
+#ifndef __X264_GTK_BITRATE_H__
+#define __X264_GTK_BITRATE_H__
+
+
+GtkWidget *_bitrate_page (X264_Gui_Config *config);
+
+
+#endif /* __X264_GTK_BITRATE_H__ */
--- /dev/null
+#include <gtk/gtk.h>
+
+#include "x264_gtk_encode_main_window.h"
+
+int
+main (int argc, char *argv[])
+{
+ g_thread_init (NULL);
+ gtk_init (&argc, &argv);
+
+ x264_gtk_encode_main_window ();
+
+ gtk_main ();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__
+# include <inttypes.h>
+#else
+# include <stdint.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "../x264.h"
+#include "../muxers.h"
+#include "x264_gtk_encode_private.h"
+
+
+#define DATA_MAX 3000000
+uint8_t data[DATA_MAX];
+
+int64_t x264_mdate (void);
+
+/* input interface */
+int (*p_open_infile)( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param );
+int (*p_get_frame_total)( hnd_t handle );
+int (*p_read_frame)( x264_picture_t *p_pic, hnd_t handle, int i_frame );
+int (*p_close_infile)( hnd_t handle );
+
+/* output interface */
+static int (*p_open_outfile) (char *filename, void **handle);
+static int (*p_set_outfile_param) (void *handle, x264_param_t *p_param);
+static int (*p_write_nalu) (void *handle, uint8_t *p_nal, int i_size);
+static int (*p_set_eop) (void *handle, x264_picture_t *p_picture);
+static int (*p_close_outfile) (void *handle);
+
+
+
+static void _set_drivers (int container);
+static int _encode_frame (x264_t *h, void *handle, x264_picture_t *pic);
+
+
+gpointer
+x264_gtk_encode_encode (X264_Thread_Data *thread_data)
+{
+ GIOStatus status;
+ gsize size;
+ X264_Pipe_Data pipe_data;
+ x264_param_t *param;
+ x264_picture_t pic;
+ x264_t *h;
+ hnd_t hin;
+ hnd_t hout;
+ int i_frame;
+ int i_frame_total;
+ int64_t i_start;
+ int64_t i_end;
+ int64_t i_file;
+ int i_frame_size;
+ int i_progress;
+
+ g_print ("encoding...\n");
+ param = thread_data->param;
+ _set_drivers (thread_data->container);
+
+ if (p_open_infile (thread_data->file_input, &hin, param)) {
+ fprintf( stderr, "could not open input file '%s'\n", thread_data->file_input );
+ return NULL;
+ }
+
+ p_open_outfile ((char *)thread_data->file_output, &hout);
+
+ i_frame_total = p_get_frame_total (hin );
+ if (((i_frame_total == 0) || (param->i_frame_total < i_frame_total)) &&
+ (param->i_frame_total > 0))
+ i_frame_total = param->i_frame_total;
+ param->i_frame_total = i_frame_total;
+
+ if ((h = x264_encoder_open (param)) == NULL)
+ {
+ fprintf (stderr, "x264_encoder_open failed\n");
+ p_close_infile (hin);
+ p_close_outfile (hout);
+ g_free (param);
+
+ return NULL;
+ }
+
+ if (p_set_outfile_param (hout, param))
+ {
+ fprintf (stderr, "can't set outfile param\n");
+ p_close_infile (hin);
+ p_close_outfile (hout);
+ g_free (param);
+
+ return NULL;
+ }
+
+ /* Create a new pic */
+ x264_picture_alloc (&pic, X264_CSP_I420, param->i_width, param->i_height );
+
+ i_start = x264_mdate();
+
+ /* Encode frames */
+ for (i_frame = 0, i_file = 0, i_progress = 0;
+ ((i_frame < i_frame_total) || (i_frame_total == 0)); )
+ {
+ if (p_read_frame (&pic, hin, i_frame))
+ break;
+
+ pic.i_pts = (int64_t)i_frame * param->i_fps_den;
+
+ i_file += _encode_frame (h, hout, &pic);
+
+ i_frame++;
+
+ /* update status line (up to 1000 times per input file) */
+ if (param->i_log_level < X264_LOG_DEBUG &&
+ (i_frame_total ? i_frame * 1000 / i_frame_total > i_progress
+ : i_frame % 10 == 0))
+ {
+ int64_t i_elapsed = x264_mdate () - i_start;
+ double fps = i_elapsed > 0 ? i_frame * 1000000. / i_elapsed : 0;
+
+ if (i_frame_total)
+ {
+ pipe_data.frame = i_frame;
+ pipe_data.frame_total = i_frame_total;
+ pipe_data.file = i_file;
+ pipe_data.elapsed = i_elapsed;
+ status = g_io_channel_write_chars (thread_data->io_write,
+ (const gchar *)&pipe_data,
+ sizeof (X264_Pipe_Data),
+ &size, NULL);
+ if (status != G_IO_STATUS_NORMAL) {
+ g_print ("Error ! %d %d %d\n", status, sizeof (X264_Pipe_Data), size);
+ }
+ else {
+ /* we force the GIOChannel to write to the pipeline */
+ status = g_io_channel_flush (thread_data->io_write,
+ NULL);
+ if (status != G_IO_STATUS_NORMAL) {
+ g_print ("Error ! %d\n", status);
+ }
+ }
+ }
+ else
+ fprintf( stderr, "encoded frames: %d, %.2f fps \r", i_frame, fps );
+ fflush( stderr ); /* needed in windows */
+ }
+ }
+ /* Flush delayed B-frames */
+ do {
+ i_file += i_frame_size = _encode_frame (h, hout, NULL);
+ } while (i_frame_size);
+
+ i_end = x264_mdate ();
+ x264_picture_clean (&pic);
+ x264_encoder_close (h);
+ fprintf (stderr, "\n");
+
+ p_close_infile (hin);
+ p_close_outfile (hout);
+
+ if (i_frame > 0) {
+ double fps = (double)i_frame * (double)1000000 /
+ (double)(i_end - i_start);
+
+ fprintf (stderr, "encoded %d frames, %.2f fps, %.2f kb/s\n",
+ i_frame, fps,
+ (double) i_file * 8 * param->i_fps_num /
+ ((double) param->i_fps_den * i_frame * 1000));
+ }
+ return NULL;
+}
+
+static void
+_set_drivers (gint container)
+{
+/* Default input file driver */
+ p_open_infile = open_file_yuv;
+ p_get_frame_total = get_frame_total_yuv;
+ p_read_frame = read_frame_yuv;
+ p_close_infile = close_file_yuv;
+
+ switch (container) {
+ case 0:
+/* Raw ES output file driver */
+ p_open_outfile = open_file_bsf;
+ p_set_outfile_param = set_param_bsf;
+ p_write_nalu = write_nalu_bsf;
+ p_set_eop = set_eop_bsf;
+ p_close_outfile = close_file_bsf;
+ break;
+ case 1:
+/* Matroska output file driver */
+ p_open_outfile = open_file_mkv;
+ p_set_outfile_param = set_param_mkv;
+ p_write_nalu = write_nalu_mkv;
+ p_set_eop = set_eop_mkv;
+ p_close_outfile = close_file_mkv;
+ break;
+#ifdef MP4_OUTPUT
+ case 2:
+ p_open_outfile = open_file_mp4;
+ p_set_outfile_param = set_param_mp4;
+ p_write_nalu = write_nalu_mp4;
+ p_set_eop = set_eop_mp4;
+ p_close_outfile = close_file_mp4;
+ break;
+#endif
+ }
+}
+
+static int
+_encode_frame (x264_t *h, void *handle, x264_picture_t *pic)
+{
+ x264_picture_t pic_out;
+ x264_nal_t *nal;
+ int i_nal;
+ int i;
+ int i_file = 0;
+
+ /* Do not force any parameters */
+ if (pic)
+ {
+ pic->i_type = X264_TYPE_AUTO;
+ pic->i_qpplus1 = 0;
+ }
+ if (x264_encoder_encode (h, &nal, &i_nal, pic, &pic_out) < 0)
+ {
+ fprintf (stderr, "x264_encoder_encode failed\n");
+ }
+
+ for (i = 0; i < i_nal; i++)
+ {
+ int i_size;
+ int i_data;
+
+ i_data = DATA_MAX;
+ if ((i_size = x264_nal_encode (data, &i_data, 1, &nal[i])) > 0 )
+ {
+ i_file += p_write_nalu (handle, data, i_size);
+ }
+ else if (i_size < 0)
+ {
+ fprintf (stderr, "need to increase buffer size (size=%d)\n", -i_size);
+ }
+ }
+ if (i_nal)
+ p_set_eop (handle, &pic_out);
+
+ return i_file;
+}
--- /dev/null
+#ifndef __X264_GTK_ENCODE_ENCODE_H__
+#define __X264_GTK_ENCODE_ENCODE_H__
+
+
+gpointer x264_gtk_encode_encode (X264_Thread_Data *thread_data);
+
+
+#endif /* __X264_GTK_ENCODE_ENCODE_H__ */
--- /dev/null
+#if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__
+# include <inttypes.h>
+#else
+# include <stdint.h>
+#endif
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+
+#include "../x264.h"
+#include "x264_gtk.h"
+#include "x264_gtk_encode_private.h"
+#include "x264_gtk_encode_encode.h"
+#include "x264_gtk_encode_status_window.h"
+
+
+typedef struct X264_Gtk_Encode_ X264_Gtk_Encode;
+
+struct X264_Gtk_Encode_
+{
+ GtkWidget *main_dialog;
+
+ /* input */
+ GtkWidget *file_input;
+ GtkWidget *width;
+ GtkWidget *height;
+ GtkWidget *fps_num;
+ GtkWidget *fps_den;
+ GtkWidget *frame_count;
+
+ /* output */
+ GtkWidget *path_output;
+ GtkWidget *file_output;
+ GtkWidget *combo;
+};
+
+
+/* Callbacks */
+static gboolean _delete_window_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
+static void _configure_window_cb (GtkButton *button,
+ gpointer user_data);
+static void _response_window_cb (GtkDialog *dialog,
+ gint res,
+ gpointer user_data);
+
+
+static gboolean _fill_status_window (GIOChannel *io,
+ GIOCondition condition,
+ gpointer user_data);
+/* Code */
+
+void
+x264_gtk_encode_main_window ()
+{
+ GtkWidget *dialog;
+ GtkWidget *frame;
+ GtkWidget *button;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkFileFilter *filter;
+ X264_Gtk_Encode *encode;
+
+ encode = (X264_Gtk_Encode *)g_malloc0 (sizeof (X264_Gtk_Encode));
+
+ dialog = gtk_dialog_new_with_buttons ("X264 Gtk Encoder",
+ NULL, 0,
+ NULL);
+ g_signal_connect (G_OBJECT (dialog),
+ "delete-event",
+ G_CALLBACK (_delete_window_cb),
+ encode);
+ g_signal_connect (G_OBJECT (dialog),
+ "response",
+ G_CALLBACK (_response_window_cb),
+ encode);
+ encode->main_dialog = dialog;
+
+ button = gtk_button_new_with_label ("Configure");
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button, FALSE, TRUE, 6);
+ g_signal_connect (G_OBJECT (button),
+ "clicked",
+ G_CALLBACK (_configure_window_cb),
+ dialog);
+ gtk_widget_show (button);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+ GTK_STOCK_EXECUTE, GTK_RESPONSE_APPLY,
+ NULL);
+
+ /* input */
+ frame = gtk_frame_new ("Input file");
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (6, 2, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Input file:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
+ gtk_widget_show (label);
+
+ encode->file_input = gtk_file_chooser_button_new ("Select a file",
+ GTK_FILE_CHOOSER_ACTION_OPEN);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (encode->file_input),
+ g_get_home_dir ());
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_add_pattern (GTK_FILE_FILTER (filter), "*.yuv");
+ gtk_file_filter_add_pattern (GTK_FILE_FILTER (filter), "*.cif");
+ gtk_file_filter_add_pattern (GTK_FILE_FILTER (filter), "*.qcif");
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (encode->file_input),
+ filter);
+ gtk_table_attach_defaults (GTK_TABLE (table), encode->file_input, 1, 2, 0, 1);
+ gtk_widget_show (encode->file_input);
+
+ label = gtk_label_new ("Width:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
+ gtk_widget_show (label);
+
+ encode->width = gtk_entry_new_with_max_length (4095);
+ gtk_entry_set_text (GTK_ENTRY (encode->width), "352");
+ gtk_table_attach_defaults (GTK_TABLE (table), encode->width, 1, 2, 1, 2);
+ gtk_widget_show (encode->width);
+
+ label = gtk_label_new ("Height:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
+ gtk_widget_show (label);
+
+ encode->height = gtk_entry_new_with_max_length (4095);
+ gtk_entry_set_text (GTK_ENTRY (encode->height), "288");
+ gtk_table_attach_defaults (GTK_TABLE (table), encode->height, 1, 2, 2, 3);
+ gtk_widget_show (encode->height);
+
+ label = gtk_label_new ("Frame rate num:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 3, 4);
+ gtk_widget_show (label);
+
+ encode->fps_num = gtk_entry_new_with_max_length (4095);
+ gtk_entry_set_text (GTK_ENTRY (encode->fps_num), "25");
+ gtk_table_attach_defaults (GTK_TABLE (table), encode->fps_num, 1, 2, 3, 4);
+ gtk_widget_show (encode->fps_num);
+
+ label = gtk_label_new ("Frame rate den:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 4, 5);
+ gtk_widget_show (label);
+
+ encode->fps_den = gtk_entry_new_with_max_length (4095);
+ gtk_entry_set_text (GTK_ENTRY (encode->fps_den), "1");
+ gtk_table_attach_defaults (GTK_TABLE (table), encode->fps_den, 1, 2, 4, 5);
+ gtk_widget_show (encode->fps_den);
+
+ label = gtk_label_new ("Frame count:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
+ gtk_widget_show (label);
+
+ encode->frame_count = gtk_entry_new_with_max_length (4095);
+ gtk_entry_set_text (GTK_ENTRY (encode->frame_count), "0");
+ gtk_table_attach_defaults (GTK_TABLE (table), encode->frame_count, 1, 2, 5, 6);
+ gtk_widget_show (encode->frame_count);
+
+ /* output */
+ frame = gtk_frame_new ("Output file");
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (3, 2, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Output path:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
+ gtk_widget_show (label);
+
+ encode->path_output = gtk_file_chooser_button_new ("Select a path",
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (encode->path_output),
+ g_get_home_dir ());
+ gtk_table_attach_defaults (GTK_TABLE (table), encode->path_output, 1, 2, 0, 1);
+ gtk_widget_show (encode->path_output);
+
+ label = gtk_label_new ("Output file (without ext.):");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
+ gtk_widget_show (label);
+
+ encode->file_output = gtk_entry_new_with_max_length (4095);
+ gtk_table_attach_defaults (GTK_TABLE (table), encode->file_output, 1, 2, 1, 2);
+ gtk_widget_show (encode->file_output);
+
+ label = gtk_label_new ("Container:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
+ gtk_widget_show (label);
+
+ encode->combo = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (encode->combo),
+ "Raw ES");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (encode->combo),
+ "Matroska");
+#ifdef MP4_OUTPUT
+ gtk_combo_box_append_text (GTK_COMBO_BOX (encode->combo),
+ "Mp4");
+#endif
+ gtk_table_attach_defaults (GTK_TABLE (table), encode->combo, 1, 2, 2, 3);
+ gtk_widget_show (encode->combo);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (encode->combo), 0);
+
+ gtk_widget_show (dialog);
+}
+
+/* Callbacks */
+
+static void
+_encode_shutdown (X264_Gtk_Encode *encode)
+{
+ if (!encode) return;
+
+ g_free (encode);
+ encode = NULL;
+}
+
+static gboolean
+_delete_window_cb (GtkWidget *widget __UNUSED__,
+ GdkEvent *event __UNUSED__,
+ gpointer user_data)
+{
+ gtk_main_quit ();
+ _encode_shutdown ((X264_Gtk_Encode *)user_data);
+
+ return TRUE;
+}
+
+static void
+_configure_window_cb (GtkButton *button __UNUSED__,
+ gpointer user_data)
+{
+ GtkWidget *window;
+
+ window = x264_gtk_window_create (GTK_WIDGET (user_data));
+ x264_gtk_shutdown (window);
+}
+
+static void
+_response_window_cb (GtkDialog *dialog,
+ gint res,
+ gpointer user_data)
+{
+ switch (res) {
+ case GTK_RESPONSE_APPLY: {
+ x264_param_t *param;
+ X264_Gtk *x264_gtk;
+ X264_Gtk_Encode *encode;
+ X264_Thread_Data *thread_data;
+ GtkWidget *win_status;
+ GThread *thread;
+ const gchar *file_input = NULL;
+ const gchar *path_output = NULL;
+ const gchar *filename_output = NULL;
+ gchar *file_output = NULL;
+ gchar *ext;
+ gint fds[2];
+ gint container;
+
+ encode = (X264_Gtk_Encode *)user_data;
+ file_input = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (encode->file_input));
+ path_output = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (encode->path_output));
+ filename_output = gtk_entry_get_text (GTK_ENTRY (encode->file_output));
+
+ if (!file_input ||
+ (file_input[0] == '\0')) {
+ GtkWidget *dialog_message;
+
+ dialog_message = gtk_message_dialog_new (GTK_WINDOW (dialog),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Error: input file name is not set");
+ gtk_dialog_run (GTK_DIALOG (dialog_message));
+ gtk_widget_destroy (dialog_message);
+ break;
+ }
+
+ if (!filename_output ||
+ (filename_output[0] == '\0')) {
+ GtkWidget *dialog_message;
+
+ dialog_message = gtk_message_dialog_new (GTK_WINDOW (dialog),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Error: output file name is not set");
+ gtk_dialog_run (GTK_DIALOG (dialog_message));
+ gtk_widget_destroy (dialog_message);
+ break;
+ }
+
+ container = gtk_combo_box_get_active (GTK_COMBO_BOX (encode->combo));
+
+ switch (container) {
+ case 0:
+ ext = ".264";
+ break;
+ case 1:
+ ext = ".mkv";
+ break;
+#ifdef MP4_OUTPUT
+ case 2:
+ ext = ".mp4";
+ break;
+#endif
+ default:
+ ext = ".264";
+ }
+
+ file_output = g_strconcat (path_output, "/", filename_output, ext, NULL);
+ g_print ("file output : %s\n", file_output);
+
+ x264_gtk = x264_gtk_load ();
+ param = x264_gtk_param_get (x264_gtk);
+ g_free (x264_gtk);
+
+ {
+ gint width;
+ gint height;
+ gint fps_num;
+ gint fps_den;
+ gint frame_count;
+
+ width = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->width)), NULL));
+ height = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->height)), NULL));
+ fps_num = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->fps_num)), NULL));
+ fps_den = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->fps_den)), NULL));
+ frame_count = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->frame_count)), NULL));
+
+ if ((width <= 0) ||
+ (height <= 0) ||
+ (fps_num <= 0) ||
+ (fps_den <= 0) ||
+ (frame_count < 0))
+ break;
+
+ param->i_width = width;
+ param->i_height = height;
+ param->i_fps_num = fps_num;
+ param->i_fps_den = fps_den;
+ param->i_frame_total = frame_count;
+ }
+
+ if (pipe (fds) == -1)
+ break;
+
+ thread_data = (X264_Thread_Data *)g_malloc0 (sizeof (X264_Thread_Data));
+ thread_data->param = param;
+ thread_data->file_input = g_strdup (file_input);
+ thread_data->file_output = g_strdup (file_output);
+ thread_data->container = container;
+ g_free (file_output);
+
+ thread_data->io_read = g_io_channel_unix_new (fds[0]);
+ g_io_channel_set_encoding (thread_data->io_read, NULL, NULL);
+ thread_data->io_write = g_io_channel_unix_new (fds[1]);
+ g_io_channel_set_encoding (thread_data->io_write, NULL, NULL);
+
+ g_io_add_watch (thread_data->io_read, G_IO_IN,
+ (GIOFunc)_fill_status_window, thread_data);
+
+ win_status = x264_gtk_encode_status_window (thread_data);
+ gtk_window_set_transient_for (GTK_WINDOW (win_status), GTK_WINDOW (dialog));
+ gtk_window_set_modal (GTK_WINDOW (win_status), TRUE);
+ gtk_widget_show (win_status);
+
+ thread = g_thread_create ((GThreadFunc)x264_gtk_encode_encode, thread_data, FALSE, NULL);
+
+ break;
+ }
+ case GTK_RESPONSE_CLOSE:
+ default:
+ gtk_main_quit ();
+ _encode_shutdown ((X264_Gtk_Encode *)user_data);
+ }
+}
+
+static gboolean
+_fill_status_window (GIOChannel *io __UNUSED__,
+ GIOCondition condition __UNUSED__,
+ gpointer user_data)
+{
+ gchar str[128];
+ X264_Thread_Data *thread_data;
+ X264_Pipe_Data pipe_data;
+ GIOStatus status;
+ gsize size;
+ gint eta;
+ gdouble progress;
+ gdouble fps;
+
+ thread_data = (X264_Thread_Data *)user_data;
+ status = g_io_channel_read_chars (thread_data->io_read,
+ (gchar *)&pipe_data,
+ sizeof (X264_Pipe_Data),
+ &size, NULL);
+ if (status != G_IO_STATUS_NORMAL) {
+ g_print ("Error ! %d %d %d\n", status, sizeof (X264_Pipe_Data), size);
+ return FALSE;
+ }
+
+ snprintf (str, 128, "%d/%d", pipe_data.frame, pipe_data.frame_total);
+ gtk_entry_set_text (GTK_ENTRY (thread_data->current_video_frame),
+ str);
+
+ snprintf (str, 128, "%dKB",
+ pipe_data.file >> 10);
+ gtk_entry_set_text (GTK_ENTRY (thread_data->video_data),
+ str);
+
+ fps = pipe_data.elapsed > 0 ? 1000000.0 * (gdouble)pipe_data.frame / (gdouble)pipe_data.elapsed : 0.0;
+ snprintf (str, 128, "%.2fKB/s (%.2f fps)",
+ (double) pipe_data.file * 8 * thread_data->param->i_fps_num /
+ ((double) thread_data->param->i_fps_den * pipe_data.frame * 1000),
+ fps);
+ gtk_entry_set_text (GTK_ENTRY (thread_data->video_rendering_rate),
+ str);
+
+ snprintf (str, 128, "%lld:%02lld:%02lld",
+ (pipe_data.elapsed / 1000000) / 3600,
+ ((pipe_data.elapsed / 1000000) / 60) % 60,
+ (pipe_data.elapsed / 1000000) % 60);
+ gtk_entry_set_text (GTK_ENTRY (thread_data->time_elapsed),
+ str);
+
+ eta = pipe_data.elapsed * (pipe_data.frame_total - pipe_data.frame) / ((int64_t)pipe_data.frame * 1000000);
+ snprintf (str, 128, "%d:%02d:%02d", eta / 3600, (eta / 60) % 60, eta % 60);
+ gtk_entry_set_text (GTK_ENTRY (thread_data->time_remaining),
+ str);
+
+ progress = (gdouble)pipe_data.frame / (gdouble)pipe_data.frame_total;
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (thread_data->progress),
+ progress);
+
+ snprintf (str, 128, "%0.1f%%", 100.0 * progress);
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (thread_data->progress), str);
+
+ return TRUE;
+}
--- /dev/null
+#ifndef __X264_GTK_ENCODE_MAIN_WINDOW_H__
+#define __X264_GTK_ENCODE_MAIN_WINDOW_H__
+
+
+void x264_gtk_encode_main_window ();
+
+
+#endif /* __X264_GTK_ENCODE_MAIN_WINDOW_H__ */
--- /dev/null
+#ifndef __X264_GTK_ENCODE_PRIVATE_H__
+#define __X264_GTK_ENCODE_PRIVATE_H__
+
+
+#define __UNUSED__ __attribute__((unused))
+
+
+typedef struct X264_Thread_Data_ X264_Thread_Data;
+typedef struct X264_Pipe_Data_ X264_Pipe_Data;
+
+struct X264_Thread_Data_
+{
+ GtkWidget *current_video_frame;
+ GtkWidget *video_data;
+ GtkWidget *video_rendering_rate;
+ GtkWidget *time_elapsed;
+ GtkWidget *time_remaining;
+ GtkWidget *progress;
+
+ GtkWidget *dialog;
+ GtkWidget *button;
+
+ x264_param_t *param;
+ gchar *file_input;
+ gchar *file_output;
+ gint container;
+
+ /* file descriptors */
+ GIOChannel *io_read; /* use it with read */
+ GIOChannel *io_write; /* use it with write */
+};
+
+struct X264_Pipe_Data_
+{
+ int frame;
+ int frame_total;
+ int file;
+ int64_t elapsed;
+};
+
+
+#endif /* __X264_GTK_ENCODE_PRIVATE_H__ */
--- /dev/null
+#if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__
+# include <inttypes.h>
+#else
+# include <stdint.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "../x264.h"
+#include "x264_gtk_encode_private.h"
+
+
+/* Callbacks */
+static gboolean _delete_window_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data);
+static void _response_window_cb (GtkDialog *dialog,
+ gint res,
+ gpointer user_data);
+
+GtkWidget *
+x264_gtk_encode_status_window (X264_Thread_Data *thread_data)
+{
+ GtkWidget *win_status;
+ GtkWidget *table;
+ GtkWidget *label;
+
+ if (!thread_data) return NULL;
+
+ win_status = thread_data->dialog = gtk_dialog_new ();
+ thread_data->button = gtk_dialog_add_button (GTK_DIALOG (win_status),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+
+ g_signal_connect (G_OBJECT (win_status),
+ "delete-event",
+ G_CALLBACK (_delete_window_cb),
+ thread_data);
+ g_signal_connect (G_OBJECT (win_status),
+ "response",
+ G_CALLBACK (_response_window_cb),
+ thread_data);
+
+ table = gtk_table_new (5, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (win_status)->vbox), table,
+ FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Current video frame:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
+ gtk_widget_show (label);
+
+ thread_data->current_video_frame = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ thread_data->current_video_frame,
+ 1, 2, 0, 1);
+ gtk_widget_show (thread_data->current_video_frame);
+
+ label = gtk_label_new ("Video data:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
+ gtk_widget_show (label);
+
+ thread_data->video_data = gtk_entry_new ();
+ gtk_entry_set_text (GTK_ENTRY (thread_data->video_data), "0KB");
+ gtk_table_attach_defaults (GTK_TABLE (table), thread_data->video_data,
+ 1, 2, 1, 2);
+ gtk_widget_show (thread_data->video_data);
+
+ label = gtk_label_new ("Video rendering rate:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
+ gtk_widget_show (label);
+
+ thread_data->video_rendering_rate = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ thread_data->video_rendering_rate,
+ 1, 2, 2, 3);
+ gtk_widget_show (thread_data->video_rendering_rate);
+
+ label = gtk_label_new ("Time elapsed:");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 3, 4);
+ gtk_widget_show (label);
+
+ thread_data->time_elapsed = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), thread_data->time_elapsed,
+ 1, 2, 3, 4);
+ gtk_widget_show (thread_data->time_elapsed);
+
+ label = gtk_label_new ("Total time (estimated):");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 4, 5);
+ gtk_widget_show (label);
+
+ thread_data->time_remaining = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), thread_data->time_remaining,
+ 1, 2, 4, 5);
+ gtk_widget_show (thread_data->time_remaining);
+
+ table = gtk_table_new (1, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (win_status)->vbox), table,
+ FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Progress:");
+ gtk_misc_set_alignment (GTK_MISC (label),
+ 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ label,
+ 0, 1,
+ 0, 1);
+ gtk_widget_show (label);
+
+ thread_data->progress = gtk_progress_bar_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), thread_data->progress,
+ 1, 2, 0, 1);
+ gtk_widget_show (thread_data->progress);
+
+ return win_status;
+}
+
+static void
+_thread_data_free (X264_Thread_Data *thread_data)
+{
+ g_free (thread_data->param);
+ g_free (thread_data->file_input);
+ g_free (thread_data->file_output);
+ g_io_channel_unref (thread_data->io_read);
+ g_io_channel_unref (thread_data->io_write);
+ g_free (thread_data);
+}
+
+static gboolean
+_delete_window_cb (GtkWidget *widget,
+ GdkEvent *event __UNUSED__,
+ gpointer user_data)
+{
+ gtk_widget_destroy (widget);
+ _thread_data_free ((X264_Thread_Data *)user_data);
+ return TRUE;
+}
+
+static void
+_response_window_cb (GtkDialog *dialog,
+ gint res,
+ gpointer user_data)
+{
+ switch (res) {
+ case GTK_RESPONSE_CANCEL:
+ default:
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ _thread_data_free ((X264_Thread_Data *)user_data);
+ }
+}
--- /dev/null
+#ifndef __X264_GTK_ENCODE_STATUS_WINDOW_H__
+#define __X264_GTK_ENCODE_STATUS_WINDOW_H__
+
+
+GtkWidget *x264_gtk_encode_status_window (X264_Thread_Data *thread_data);
+
+
+#endif /* __X264_GTK_ENCODE_STATUS_WINDOW_H__ */
--- /dev/null
+#ifndef __X264_GTK_ENUM_H__
+#define __X264_GTK_ENUM_H__
+
+
+typedef enum
+{
+ X264_PASS_SINGLE_BITRATE,
+ X264_PASS_SINGLE_QUANTIZER,
+ X264_PASS_MULTIPASS_1ST,
+ X264_PASS_MULTIPASS_1ST_FAST,
+ X264_PASS_MULTIPASS_NTH
+}X264_Pass;
+
+typedef enum
+{
+ X264_NONE = X264_DIRECT_PRED_NONE,
+ X264_SPATIAL = X264_DIRECT_PRED_SPATIAL,
+ X264_TEMPORAL = X264_DIRECT_PRED_TEMPORAL
+}X264_Direct_Mode;
+
+typedef enum
+{
+ X264_PD_1,
+ X264_PD_2,
+ X264_PD_3,
+ X264_PD_4,
+ X264_PD_5,
+ X264_PD_6,
+ X264_PD_6b
+}X264_Partition_Decision;
+
+typedef enum
+{
+ X264_ME_METHOD_DIAMOND = X264_ME_DIA,
+ X264_ME_METHOD_HEXAGONAL = X264_ME_HEX,
+ X264_ME_METHOD_UNEVEN_MULTIHEXA = X264_ME_UMH,
+ X264_ME_METHOD_EXHAUSTIVE = X264_ME_ESA
+}X264_Me_Method;
+
+typedef enum
+{
+ X264_DEBUG_METHOD_NONE = X264_LOG_NONE,
+ X264_DEBUG_METHOD_ERROR = X264_LOG_ERROR,
+ X264_DEBUG_METHOD_WARNING = X264_LOG_WARNING,
+ X264_DEBUG_METHOD_INFO = X264_LOG_INFO,
+ X264_DEBUG_METHOD_DEBUG = X264_LOG_DEBUG
+}X264_Debug_Method;
+
+
+#endif /* __X264_GTK_ENUM_H__ */
--- /dev/null
+#include <gtk/gtk.h>
+
+#include "x264_gtk_private.h"
+
+
+GtkWidget *
+_mb_page (X264_Gui_Config *config)
+{
+ GtkWidget *vbox;
+ GtkWidget *frame;
+ GtkWidget *vbox2;
+ GtkWidget *table;
+ GtkWidget *label;
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+
+ /* Partitions */
+ frame = gtk_frame_new ("Partitions");
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ vbox2 = gtk_vbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox2), 6);
+ gtk_container_add (GTK_CONTAINER (frame), vbox2);
+ gtk_widget_show (vbox2);
+
+ config->mb.partitions.transform_8x8 = gtk_check_button_new_with_label ("8x8 Transform");
+ gtk_box_pack_start (GTK_BOX (vbox2), config->mb.partitions.transform_8x8, FALSE, TRUE, 0);
+ gtk_widget_show (config->mb.partitions.transform_8x8);
+
+ config->mb.partitions.pframe_search_8 = gtk_check_button_new_with_label ("8x16, 16x8 and 8x8 P-frame search");
+ gtk_box_pack_start (GTK_BOX (vbox2), config->mb.partitions.pframe_search_8, FALSE, TRUE, 0);
+ gtk_widget_show (config->mb.partitions.pframe_search_8);
+
+ config->mb.partitions.bframe_search_8 = gtk_check_button_new_with_label ("8x16, 16x8 and 8x8 B-frame search");
+ gtk_box_pack_start (GTK_BOX (vbox2), config->mb.partitions.bframe_search_8, FALSE, TRUE, 0);
+ gtk_widget_show (config->mb.partitions.bframe_search_8);
+
+ config->mb.partitions.pframe_search_4 = gtk_check_button_new_with_label ("4x8, 8x4 and 4x4 P-frame search");
+ gtk_box_pack_start (GTK_BOX (vbox2), config->mb.partitions.pframe_search_4, FALSE, TRUE, 0);
+ gtk_widget_show (config->mb.partitions.pframe_search_4);
+
+ config->mb.partitions.inter_search_8 = gtk_check_button_new_with_label ("8x8 Intra search");
+ gtk_box_pack_start (GTK_BOX (vbox2), config->mb.partitions.inter_search_8, FALSE, TRUE, 0);
+ gtk_widget_show (config->mb.partitions.inter_search_8);
+
+ config->mb.partitions.inter_search_4 = gtk_check_button_new_with_label ("4x4 Intra search");
+ gtk_box_pack_start (GTK_BOX (vbox2), config->mb.partitions.inter_search_4, FALSE, TRUE, 0);
+ gtk_widget_show (config->mb.partitions.inter_search_4);
+
+ /* B-Frames */
+ frame = gtk_frame_new ("B-Frames");
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (5, 2, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Max consecutive");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 0, 1);
+ gtk_widget_show (label);
+
+ config->mb.bframes.max_consecutive = gtk_entry_new_with_max_length (3);
+ gtk_table_attach_defaults (GTK_TABLE (table), config->mb.bframes.max_consecutive,
+ 1, 2, 0, 1);
+ gtk_widget_show (config->mb.bframes.max_consecutive);
+
+ label = gtk_label_new ("Bias");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 1, 2);
+ gtk_widget_show (label);
+
+ config->mb.bframes.bias = gtk_hscale_new_with_range (-100.0, 100.0, 1.0);
+ gtk_scale_set_digits (GTK_SCALE (config->mb.bframes.bias), 0);
+ gtk_scale_set_value_pos (GTK_SCALE (config->mb.bframes.bias), GTK_POS_RIGHT);
+ gtk_table_attach_defaults (GTK_TABLE (table), config->mb.bframes.bias,
+ 1, 2, 1, 2);
+ gtk_widget_show (config->mb.bframes.bias);
+
+ config->mb.bframes.use_as_reference = gtk_check_button_new_with_label ("Use as references");
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->mb.bframes.use_as_reference,
+ 0, 1, 2, 3);
+ gtk_widget_show (config->mb.bframes.use_as_reference);
+
+ config->mb.bframes.bidir_me = gtk_check_button_new_with_label ("Bidirectional ME");
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->mb.bframes.bidir_me,
+ 1, 2, 2, 3);
+ gtk_widget_show (config->mb.bframes.bidir_me);
+
+ config->mb.bframes.adaptive = gtk_check_button_new_with_label ("Adaptive");
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->mb.bframes.adaptive,
+ 0, 1, 3, 4);
+ gtk_widget_show (config->mb.bframes.adaptive);
+
+ config->mb.bframes.weighted_biprediction = gtk_check_button_new_with_label ("Weighted biprediction");
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->mb.bframes.weighted_biprediction,
+ 1, 2, 3, 4);
+ gtk_widget_show (config->mb.bframes.weighted_biprediction);
+
+ label = gtk_label_new ("Direct mode");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 4, 5);
+ gtk_widget_show (label);
+
+ config->mb.bframes.direct_mode = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->mb.bframes.direct_mode),
+ "None");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->mb.bframes.direct_mode),
+ "Spatial");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->mb.bframes.direct_mode),
+ "Temporal");
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->mb.bframes.direct_mode,
+ 1, 2, 4, 5);
+ gtk_widget_show (config->mb.bframes.direct_mode);
+
+ return vbox;
+}
--- /dev/null
+#ifndef __X264_GTK_MB_H__
+#define __X264_GTK_MB_H__
+
+
+GtkWidget *_mb_page (X264_Gui_Config *config);
+
+
+#endif /* __X264_GTK_MB_H__ */
--- /dev/null
+#include <gtk/gtk.h>
+
+#include "x264_gtk_private.h"
+
+
+/* Callbacks */
+static void _more_deblocking_filter (GtkToggleButton *button,
+ gpointer user_data);
+static void _more_cabac (GtkToggleButton *button,
+ gpointer user_data);
+
+
+GtkWidget *
+_more_page (X264_Gui_Config *config)
+{
+ GtkWidget *vbox;
+ GtkWidget *frame;
+ GtkWidget *hbox;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkRequisition size;
+ GtkRequisition size2;
+ GtkRequisition size3;
+ GtkRequisition size4;
+ GtkRequisition size5;
+
+ label = gtk_entry_new_with_max_length (3);
+ gtk_widget_size_request (label, &size);
+ gtk_widget_destroy (GTK_WIDGET (label));
+
+ label = gtk_check_button_new_with_label ("Deblocking Filter");
+ gtk_widget_size_request (label, &size2);
+ gtk_widget_destroy (GTK_WIDGET (label));
+
+ label = gtk_label_new ("Partition decision");
+ gtk_widget_size_request (label, &size3);
+ gtk_widget_destroy (GTK_WIDGET (label));
+
+ label = gtk_label_new ("Threshold");
+ gtk_widget_size_request (label, &size5);
+ gtk_widget_destroy (GTK_WIDGET (label));
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+
+ /* Motion Estimation */
+ frame = gtk_frame_new ("Motion Estimation");
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (4, 3, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Partition decision");
+ gtk_widget_set_size_request (label, size2.width, size3.height);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 2, 0, 1);
+ gtk_widget_show (label);
+
+ config->more.motion_estimation.partition_decision = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision),
+ "1 (Fastest)");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision),
+ "2");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision),
+ "3");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision),
+ "4");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision),
+ "5 (High quality)");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision),
+ "6 (RDO)");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.motion_estimation.partition_decision),
+ "6b (RDO on B frames)");
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.motion_estimation.partition_decision,
+ 1, 3, 0, 1);
+ gtk_widget_show (config->more.motion_estimation.partition_decision);
+
+ label = gtk_label_new ("Method");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 2, 1, 2);
+ gtk_widget_show (label);
+
+ config->more.motion_estimation.method = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.motion_estimation.method),
+ "Diamond Search");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.motion_estimation.method),
+ "Hexagonal Search");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.motion_estimation.method),
+ "Uneven Multi-Hexagon");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.motion_estimation.method),
+ "Exhaustive search");
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.motion_estimation.method,
+ 1, 3, 1, 2);
+ gtk_widget_show (config->more.motion_estimation.method);
+
+ label = gtk_label_new ("Range");
+ gtk_widget_size_request (label, &size4);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 2, 3);
+ gtk_widget_show (label);
+
+ config->more.motion_estimation.range = gtk_entry_new_with_max_length (3);
+ gtk_widget_set_size_request (config->more.motion_estimation.range,
+ 20, size.height);
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.motion_estimation.range,
+ 1, 2, 2, 3);
+ gtk_widget_show (config->more.motion_estimation.range);
+
+ config->more.motion_estimation.chroma_me = gtk_check_button_new_with_label ("Chroma ME");
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.motion_estimation.chroma_me,
+ 2, 3, 2, 3);
+ gtk_widget_show (config->more.motion_estimation.chroma_me);
+
+ label = gtk_label_new ("Max Ref. frames");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 3, 4);
+ gtk_widget_show (label);
+
+ config->more.motion_estimation.max_ref_frames = gtk_entry_new_with_max_length (3);
+ gtk_widget_set_size_request (config->more.motion_estimation.max_ref_frames,
+ 20, size.height);
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.motion_estimation.max_ref_frames,
+ 1, 2, 3, 4);
+ gtk_widget_show (config->more.motion_estimation.max_ref_frames);
+
+ config->more.motion_estimation.mixed_refs = gtk_check_button_new_with_label ("Mixed Refs");
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.motion_estimation.mixed_refs,
+ 2, 3, 3, 4);
+ gtk_widget_show (config->more.motion_estimation.mixed_refs);
+
+ /* Misc. Options */
+ frame = gtk_frame_new ("Misc. Options");
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (5, 4, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Sample AR");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 0, 1);
+ gtk_widget_show (label);
+
+ hbox = gtk_hbox_new (TRUE, 6);
+ gtk_table_attach_defaults (GTK_TABLE (table), hbox,
+ 1, 2, 0, 1);
+ gtk_widget_show (hbox);
+
+ config->more.misc.sample_ar_x = gtk_entry_new_with_max_length (3);
+ gtk_widget_set_size_request (config->more.misc.sample_ar_x, 25, size.height);
+ gtk_box_pack_start (GTK_BOX (hbox), config->more.misc.sample_ar_x, FALSE, TRUE, 0);
+ gtk_widget_show (config->more.misc.sample_ar_x);
+
+ config->more.misc.sample_ar_y = gtk_entry_new_with_max_length (3);
+ gtk_widget_set_size_request (config->more.misc.sample_ar_y, 25, size.height);
+ gtk_box_pack_start (GTK_BOX (hbox), config->more.misc.sample_ar_y, FALSE, TRUE, 0);
+ gtk_widget_show (config->more.misc.sample_ar_y);
+
+ label = gtk_label_new ("Threads");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 2, 3, 0, 1);
+ gtk_widget_show (label);
+
+ config->more.misc.threads = gtk_entry_new_with_max_length (3);
+ gtk_widget_set_size_request (config->more.misc.threads, size5.width, size.height);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->more.misc.threads,
+ 3, 4, 0, 1);
+ gtk_widget_show (config->more.misc.threads);
+
+ config->more.misc.cabac = gtk_check_button_new_with_label ("CABAC");
+ gtk_widget_set_size_request (config->more.misc.cabac, size5.width, size.height);
+ g_signal_connect (G_OBJECT (config->more.misc.cabac),
+ "toggled",
+ G_CALLBACK (_more_cabac), config);
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.misc.cabac,
+ 0, 1, 1, 2);
+ gtk_widget_show (config->more.misc.cabac);
+
+ label = gtk_label_new ("Trellis");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 1, 2, 1, 2);
+ gtk_widget_show (label);
+
+ config->more.misc.trellis = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.misc.trellis),
+ "Disabled");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.misc.trellis),
+ "Enabled (once)");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.misc.trellis),
+ "Enabled (mode decision)");
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.misc.trellis,
+ 2, 4, 1, 2);
+ gtk_widget_show (config->more.misc.trellis);
+
+ label = gtk_label_new ("Noise reduction");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 2, 3);
+ gtk_widget_show (label);
+
+ config->more.misc.noise_reduction = gtk_entry_new_with_max_length (3);
+ gtk_widget_set_size_request (config->more.misc.noise_reduction, size5.width, size.height);
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.misc.noise_reduction,
+ 1, 2, 2, 3);
+ gtk_widget_show (config->more.misc.noise_reduction);
+
+ config->more.misc.df.deblocking_filter = gtk_check_button_new_with_label ("Deblocking Filter");
+ g_signal_connect (G_OBJECT (config->more.misc.df.deblocking_filter),
+ "toggled",
+ G_CALLBACK (_more_deblocking_filter), config);
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.misc.df.deblocking_filter,
+ 0, 1, 3, 4);
+ gtk_widget_show (config->more.misc.df.deblocking_filter);
+
+ label = gtk_label_new ("Strength");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_set_size_request (label, size5.width, size4.height);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 1, 2, 3, 4);
+ gtk_widget_show (label);
+
+ config->more.misc.df.strength = gtk_hscale_new_with_range (-6.0, 6.0, 1.0);
+ gtk_widget_size_request (config->more.misc.df.strength, &size4);
+ gtk_scale_set_digits (GTK_SCALE (config->more.misc.df.strength), 0);
+ gtk_scale_set_value_pos (GTK_SCALE (config->more.misc.df.strength), GTK_POS_RIGHT);
+ // gtk_widget_set_size_request (config->more.misc.df.strength, size5.width, size4.height);
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.misc.df.strength,
+ 2, 4, 3, 4);
+ gtk_widget_show (config->more.misc.df.strength);
+
+ label = gtk_label_new ("Threshold");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_set_size_request (label, size5.width, size4.height);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 1, 2, 4, 5);
+ gtk_widget_show (label);
+
+ config->more.misc.df.threshold = gtk_hscale_new_with_range (-6.0, 6.0, 1.0);
+ gtk_scale_set_digits (GTK_SCALE (config->more.misc.df.threshold), 0);
+ gtk_scale_set_value_pos (GTK_SCALE (config->more.misc.df.threshold), GTK_POS_RIGHT);
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.misc.df.threshold,
+ 2, 4, 4, 5);
+ gtk_widget_show (config->more.misc.df.threshold);
+
+ /* Debug */
+ frame = gtk_frame_new ("Debug");
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (2, 2, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Log level");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_set_size_request (label, size2.width, size3.height);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 0, 1);
+ gtk_widget_show (label);
+
+ config->more.debug.log_level = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.debug.log_level),
+ "None");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.debug.log_level),
+ "Error");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.debug.log_level),
+ "Warning");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.debug.log_level),
+ "Info");
+ gtk_combo_box_append_text (GTK_COMBO_BOX (config->more.debug.log_level),
+ "Debug");
+ gtk_table_attach_defaults (GTK_TABLE (table), config->more.debug.log_level,
+ 1, 2, 0, 1);
+ gtk_widget_show (config->more.debug.log_level);
+
+ label = gtk_label_new ("FourCC");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 1, 2);
+ gtk_widget_show (label);
+
+ config->more.debug.fourcc = gtk_entry_new_with_max_length (4);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->more.debug.fourcc,
+ 1, 2, 1, 2);
+ gtk_widget_show (config->more.debug.fourcc);
+
+
+
+ return vbox;
+}
+
+/* Callbacks */
+static void
+_more_deblocking_filter (GtkToggleButton *button,
+ gpointer user_data)
+{
+ X264_Gui_Config *config;
+
+ config = (X264_Gui_Config *)user_data;
+
+ if (gtk_toggle_button_get_active (button)) {
+ gtk_widget_set_sensitive (config->more.misc.df.strength, TRUE);
+ gtk_widget_set_sensitive (config->more.misc.df.threshold, TRUE);
+ }
+ else {
+ gtk_widget_set_sensitive (config->more.misc.df.strength, FALSE);
+ gtk_widget_set_sensitive (config->more.misc.df.threshold, FALSE);
+ }
+}
+
+static void
+_more_cabac (GtkToggleButton *button,
+ gpointer user_data)
+{
+ X264_Gui_Config *config;
+
+ config = (X264_Gui_Config *)user_data;
+
+ if (gtk_toggle_button_get_active (button))
+ gtk_widget_set_sensitive (config->more.misc.trellis, TRUE);
+ else
+ gtk_widget_set_sensitive (config->more.misc.trellis, FALSE);
+}
--- /dev/null
+#ifndef __X264_GTK_MORE_H__
+#define __X264_GTK_MORE_H__
+
+
+GtkWidget *_more_page (X264_Gui_Config *config);
+
+
+#endif /* __X264_GTK_MORE_H__ */
--- /dev/null
+#ifndef __X264_GTK_PRIVATE_H__
+#define __X264_GTK_PRIVATE_H__
+
+
+#define __UNUSED__ __attribute__((unused))
+
+
+typedef struct Bitrate_ Bitrate;
+typedef struct Rate_Control_ Rate_Control;
+typedef struct MB_ MB;
+typedef struct More_ More;
+typedef struct Zones_ Zones;
+typedef struct X264_Gui_Config_ X264_Gui_Config;
+typedef struct X264_Gui_Zone_ X264_Gui_Zone;
+
+struct Bitrate_
+{
+ GtkWidget *pass;
+ GtkWidget *label;
+ GtkWidget *w_quantizer;
+ GtkWidget *w_average_bitrate;
+ GtkWidget *w_target_bitrate;
+
+ GtkWidget *update_statfile;
+ GtkWidget *statsfile_name;
+};
+
+struct Rate_Control_
+{
+ /* bitrate */
+ struct
+ {
+ GtkWidget *keyframe_boost;
+ GtkWidget *bframes_reduction;
+ GtkWidget *bitrate_variability;
+ }bitrate;
+
+ /* Quantization Limits */
+ struct
+ {
+ GtkWidget *min_qp;
+ GtkWidget *max_qp;
+ GtkWidget *max_qp_step;
+ }quantization_limits;
+
+ /* Scene Cuts */
+ struct
+ {
+ GtkWidget *scene_cut_threshold;
+ GtkWidget *min_idr_frame_interval;
+ GtkWidget *max_idr_frame_interval;
+ }scene_cuts;
+
+};
+
+struct MB_
+{
+ /* Partitions */
+ struct
+ {
+ GtkWidget *transform_8x8;
+ GtkWidget *pframe_search_8;
+ GtkWidget *bframe_search_8;
+ GtkWidget *pframe_search_4;
+ GtkWidget *inter_search_8;
+ GtkWidget *inter_search_4;
+ }partitions;
+
+ /* B-frames */
+ struct
+ {
+ GtkWidget *use_as_reference;
+ GtkWidget *bidir_me;
+ GtkWidget *adaptive;
+ GtkWidget *weighted_biprediction;
+ GtkWidget *max_consecutive;
+ GtkWidget *bias;
+ GtkWidget *direct_mode;
+ }bframes;
+
+};
+
+struct More_
+{
+ /* Motion estimation */
+ struct
+ {
+ GtkWidget *partition_decision;
+ GtkWidget *method;
+ GtkWidget *range;
+ GtkWidget *chroma_me;
+ GtkWidget *max_ref_frames;
+ GtkWidget *mixed_refs;
+ }motion_estimation;
+
+ /* Misc. Options */
+ struct
+ {
+ GtkWidget *sample_ar_x;
+ GtkWidget *sample_ar_y;
+ GtkWidget *threads;
+ GtkWidget *cabac;
+ GtkWidget *trellis;
+ GtkWidget *noise_reduction;
+
+ struct
+ {
+ GtkWidget *deblocking_filter;
+ GtkWidget *strength;
+ GtkWidget *threshold;
+ }df;
+
+ }misc;
+
+ struct
+ {
+ GtkWidget *log_level;
+ GtkWidget *fourcc;
+ }debug;
+
+};
+
+struct Zones_
+{
+ GtkWidget *list_zones;
+};
+
+struct X264_Gui_Config_
+{
+ Bitrate bitrate;
+ Rate_Control rate_control;
+ MB mb;
+ More more;
+ Zones zones;
+};
+
+struct X264_Gui_Zone_
+{
+ GtkWidget *entry_start_frame;
+ GtkWidget *radio_qp;
+ GtkWidget *entry_qp;
+ GtkWidget *entry_weight;
+};
+
+
+#endif /* __X264_GTK_PRIVATE_H__ */
--- /dev/null
+#include <gtk/gtk.h>
+
+#include "x264_gtk_private.h"
+
+
+/* Callbacks */
+static void _insert_numeric (GtkEditable *editable,
+ const gchar *text,
+ gint length,
+ gint *position,
+ gpointer data);
+
+GtkWidget *
+_rate_control_page (X264_Gui_Config *config)
+{
+ GtkWidget *vbox;
+ GtkWidget *frame;
+ GtkWidget *table;
+ GtkWidget *label;
+
+ vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+
+ /* bitrate */
+ frame = gtk_frame_new ("Bitrate");
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (3, 2, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Keyframe boost (%)");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 0, 1);
+ gtk_widget_show (label);
+
+ config->rate_control.bitrate.keyframe_boost = gtk_entry_new_with_max_length (3);
+ g_signal_connect (G_OBJECT (config->rate_control.bitrate.keyframe_boost),
+ "insert-text",
+ G_CALLBACK (_insert_numeric),
+ NULL);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->rate_control.bitrate.keyframe_boost,
+ 1, 2, 0, 1);
+ gtk_widget_show (config->rate_control.bitrate.keyframe_boost);
+
+ label = gtk_label_new ("B-frames reduction (%)");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 1, 2);
+ gtk_widget_show (label);
+
+ config->rate_control.bitrate.bframes_reduction = gtk_entry_new_with_max_length (5);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->rate_control.bitrate.bframes_reduction,
+ 1, 2, 1, 2);
+ gtk_widget_show (config->rate_control.bitrate.bframes_reduction);
+
+ label = gtk_label_new ("Bitrate variability (%)");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 2, 3);
+ gtk_widget_show (label);
+
+ config->rate_control.bitrate.bitrate_variability = gtk_entry_new_with_max_length (3);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->rate_control.bitrate.bitrate_variability,
+ 1, 2, 2, 3);
+ gtk_widget_show (config->rate_control.bitrate.bitrate_variability);
+
+ /* Quantization limits */
+ frame = gtk_frame_new ("Quantization limits");
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (3, 2, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Min QP");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 0, 1);
+ gtk_widget_show (label);
+
+ config->rate_control.quantization_limits.min_qp = gtk_entry_new_with_max_length (3);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->rate_control.quantization_limits.min_qp,
+ 1, 2, 0, 1);
+ gtk_widget_show (config->rate_control.quantization_limits.min_qp);
+
+ label = gtk_label_new ("Max QP");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 1, 2);
+ gtk_widget_show (label);
+
+ config->rate_control.quantization_limits.max_qp = gtk_entry_new_with_max_length (3);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->rate_control.quantization_limits.max_qp,
+ 1, 2, 1, 2);
+ gtk_widget_show (config->rate_control.quantization_limits.max_qp);
+
+ label = gtk_label_new ("Max QP Step");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 2, 3);
+ gtk_widget_show (label);
+
+ config->rate_control.quantization_limits.max_qp_step = gtk_entry_new_with_max_length (3);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->rate_control.quantization_limits.max_qp_step,
+ 1, 2, 2, 3);
+ gtk_widget_show (config->rate_control.quantization_limits.max_qp_step);
+
+ /* Scene Cuts */
+ frame = gtk_frame_new ("Scene Cuts");
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 6);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (3, 2, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ label = gtk_label_new ("Scene Cut Threshold");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 0, 1);
+ gtk_widget_show (label);
+
+ config->rate_control.scene_cuts.scene_cut_threshold = gtk_entry_new_with_max_length (3);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->rate_control.scene_cuts.scene_cut_threshold,
+ 1, 2, 0, 1);
+ gtk_widget_show (config->rate_control.scene_cuts.scene_cut_threshold);
+
+ label = gtk_label_new ("Min IDR-frame interval");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 1, 2);
+ gtk_widget_show (label);
+
+ config->rate_control.scene_cuts.min_idr_frame_interval = gtk_entry_new_with_max_length (3);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->rate_control.scene_cuts.min_idr_frame_interval,
+ 1, 2, 1, 2);
+ gtk_widget_show (config->rate_control.scene_cuts.min_idr_frame_interval);
+
+ label = gtk_label_new ("Max IDR-frame interval");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label,
+ 0, 1, 2, 3);
+ gtk_widget_show (label);
+
+ config->rate_control.scene_cuts.max_idr_frame_interval = gtk_entry_new_with_max_length (3);
+ gtk_table_attach_defaults (GTK_TABLE (table),
+ config->rate_control.scene_cuts.max_idr_frame_interval,
+ 1, 2, 2, 3);
+ gtk_widget_show (config->rate_control.scene_cuts.max_idr_frame_interval);
+
+
+ return vbox;
+}
+
+static void
+_insert_numeric (GtkEditable *editable,
+ const gchar *text,
+ gint length,
+ gint *position,
+ gpointer data)
+{
+ gint i;
+ gint j;
+ gchar *result;
+
+ result = (gchar *)g_malloc (sizeof (gchar) * (length + 1));
+ if (!result)
+ return;
+
+ for (i = 0, j = 0; i < length; i++)
+ {
+ if (g_ascii_isdigit (text[i]))
+ {
+ result[j] = text[i];
+ j++;
+ }
+ }
+ result[j] = '\0';
+
+ g_signal_handlers_block_by_func (editable,
+ (gpointer) _insert_numeric, data);
+ gtk_editable_insert_text (editable, result, j, position);
+ g_signal_handlers_unblock_by_func (editable,
+ (gpointer) _insert_numeric, data);
+
+ g_signal_stop_emission_by_name (editable, "insert-text");
+
+ g_free (result);
+}
+
--- /dev/null
+#ifndef __X264_GTK_RC_H__
+#define __X264_GTK_RC_H__
+
+
+GtkWidget *_rate_control_page (X264_Gui_Config *config);
+
+
+#endif /* __X264_GTK_RC_H__ */