1 /*****************************************************************************
2 * x264_gtk_encode_main_window.c: h264 gtk encoder frontend
3 *****************************************************************************
4 * Copyright (C) 2006 Vincent Torri
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
19 *****************************************************************************/
21 #if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__
22 # include <inttypes.h>
27 #ifdef _WIN32 /* Needed to define _O_BINARY */
29 # define strncasecmp _strnicmp
33 #include <sys/stat.h> /* For stat */
38 #include "../config.h"
39 #include "x264_icon.h"
41 #include "x264_gtk_i18n.h"
42 #include "x264_gtk_demuxers.h"
43 #include "x264_gtk_encode_private.h"
44 #include "x264_gtk_encode_encode.h"
45 #include "x264_gtk_encode_status_window.h"
48 typedef struct X264_Gtk_Encode_ X264_Gtk_Encode;
50 struct X264_Gtk_Encode_
52 GtkWidget *main_dialog;
55 X264_Demuxer_Type container;
56 guint64 size; /* For YUV formats */
57 GtkWidget *file_input;
62 GtkWidget *frame_count;
65 GtkWidget *path_output;
66 GtkWidget *file_output;
72 static gboolean x264_delete_window_cb (GtkWidget *widget,
75 static void x264_configure_window_cb (GtkButton *button,
77 static void x264_chooser_window_cb (GtkDialog *dialog,
80 static void x264_response_window_cb (GtkDialog *dialog,
83 static void x264_dimension_entry_cb (GtkEditable *editable,
86 static gboolean x264_fill_status_window (GIOChannel *io,
87 GIOCondition condition,
91 x264_file_size(const char* name)
94 memset(&buf, 0, sizeof(struct stat));
96 if (stat(name, &buf) < 0)
98 fprintf(stderr, _("Can't stat file\n"));
105 x264_gtk_encode_main_window ()
112 GtkFileChooser *chooser;
113 GtkFileFilter *filter;
115 X264_Gtk_Encode *encode;
117 encode = (X264_Gtk_Encode *)g_malloc0 (sizeof (X264_Gtk_Encode));
119 dialog = gtk_dialog_new_with_buttons (_("X264 Gtk Encoder"),
122 icon = gdk_pixbuf_new_from_inline (-1, x264_icon,
124 gtk_window_set_icon (GTK_WINDOW (dialog), icon);
125 g_signal_connect (G_OBJECT (dialog),
127 G_CALLBACK (x264_delete_window_cb),
129 g_signal_connect (G_OBJECT (dialog),
131 G_CALLBACK (x264_response_window_cb),
133 encode->main_dialog = dialog;
135 button = gtk_button_new_with_label (_("Configure"));
136 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button, FALSE, TRUE, 6);
137 g_signal_connect (G_OBJECT (button),
139 G_CALLBACK (x264_configure_window_cb),
141 gtk_widget_show (button);
143 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
144 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
145 GTK_STOCK_EXECUTE, GTK_RESPONSE_APPLY,
149 frame = gtk_frame_new (_("Input file"));
150 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, FALSE, TRUE, 6);
151 gtk_widget_show (frame);
153 table = gtk_table_new (6, 2, TRUE);
154 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
155 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
156 gtk_container_set_border_width (GTK_CONTAINER (table), 6);
157 gtk_container_add (GTK_CONTAINER (frame), table);
158 gtk_widget_show (table);
160 label = gtk_label_new (_("Input file:"));
161 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
162 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
163 gtk_widget_show (label);
165 chooser = (GtkFileChooser*)
166 gtk_file_chooser_dialog_new(_("Select a file"),
168 GTK_FILE_CHOOSER_ACTION_OPEN,
169 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
170 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
172 gtk_file_chooser_set_current_folder (chooser, g_get_home_dir ());
174 filter = gtk_file_filter_new ();
175 gtk_file_filter_set_name (filter, _("All supported"));
176 gtk_file_filter_add_pattern (filter, "*.yuv");
177 gtk_file_filter_add_pattern (filter, "*.cif");
178 gtk_file_filter_add_pattern (filter, "*.qcif");
179 gtk_file_filter_add_pattern (filter, "*.y4m");
181 gtk_file_filter_add_pattern (filter, "*.avs");
182 gtk_file_filter_add_pattern (filter, "*.avi");
184 gtk_file_chooser_add_filter (chooser, filter);
186 filter = gtk_file_filter_new ();
187 gtk_file_filter_set_name (filter, _("YUV sequence"));
188 gtk_file_filter_add_pattern (filter, "*.yuv");
189 gtk_file_chooser_add_filter (chooser, filter);
192 filter = gtk_file_filter_new ();
193 gtk_file_filter_set_name (filter, _("YUV CIF sequence"));
194 gtk_file_filter_add_pattern (filter, "*.cif");
195 gtk_file_chooser_add_filter (chooser, filter);
198 filter = gtk_file_filter_new ();
199 gtk_file_filter_set_name (filter, _("YUV QCIF sequence"));
200 gtk_file_filter_add_pattern (filter, "*.qcif");
201 gtk_file_chooser_add_filter (chooser, filter);
203 /* YUV4MPEG2 filter */
204 filter = gtk_file_filter_new ();
205 gtk_file_filter_set_name (filter, _("YUV4MPEG2 sequence"));
206 gtk_file_filter_add_pattern (filter, "*.y4m");
207 gtk_file_chooser_add_filter (chooser, filter);
211 filter = gtk_file_filter_new ();
212 gtk_file_filter_set_name (filter, "AVI");
213 gtk_file_filter_add_pattern (filter, "*.avi");
214 gtk_file_chooser_add_filter (chooser, filter);
216 filter = gtk_file_filter_new ();
217 gtk_file_filter_set_name (filter, _("Avisynth Script"));
218 gtk_file_filter_add_pattern (filter, "*.avs");
219 gtk_file_chooser_add_filter (chooser, filter);
221 g_signal_connect_after(G_OBJECT (chooser), "response",
222 G_CALLBACK (x264_chooser_window_cb),
224 encode->file_input = gtk_file_chooser_button_new_with_dialog (GTK_WIDGET(chooser));
225 gtk_table_attach_defaults (GTK_TABLE (table), encode->file_input, 1, 2, 0, 1);
226 gtk_widget_show (encode->file_input);
228 label = gtk_label_new (_("Width:"));
229 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
230 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
231 gtk_widget_show (label);
233 encode->width = gtk_entry_new_with_max_length (255);
234 gtk_entry_set_text (GTK_ENTRY (encode->width), "352");
235 g_signal_connect_after(G_OBJECT (encode->width), "changed",
236 G_CALLBACK (x264_dimension_entry_cb),
238 gtk_table_attach_defaults (GTK_TABLE (table), encode->width, 1, 2, 1, 2);
239 gtk_widget_show (encode->width);
241 label = gtk_label_new (_("Height:"));
242 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
243 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
244 gtk_widget_show (label);
246 encode->height = gtk_entry_new_with_max_length (255);
247 gtk_entry_set_text (GTK_ENTRY (encode->height), "288");
248 gtk_table_attach_defaults (GTK_TABLE (table), encode->height, 1, 2, 2, 3);
249 g_signal_connect_after(G_OBJECT (encode->height), "changed",
250 G_CALLBACK (x264_dimension_entry_cb),
252 gtk_widget_show (encode->height);
254 label = gtk_label_new (_("Frame rate num:"));
255 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
256 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 3, 4);
257 gtk_widget_show (label);
259 encode->fps_num = gtk_entry_new_with_max_length (255);
260 gtk_entry_set_text (GTK_ENTRY (encode->fps_num), "25");
261 gtk_table_attach_defaults (GTK_TABLE (table), encode->fps_num, 1, 2, 3, 4);
262 gtk_widget_show (encode->fps_num);
264 label = gtk_label_new (_("Frame rate den:"));
265 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
266 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 4, 5);
267 gtk_widget_show (label);
269 encode->fps_den = gtk_entry_new_with_max_length (255);
270 gtk_entry_set_text (GTK_ENTRY (encode->fps_den), "1");
271 gtk_table_attach_defaults (GTK_TABLE (table), encode->fps_den, 1, 2, 4, 5);
272 gtk_widget_show (encode->fps_den);
274 label = gtk_label_new (_("Frame count:"));
275 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
276 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
277 gtk_widget_show (label);
279 encode->frame_count = gtk_entry_new_with_max_length (255);
280 gtk_entry_set_text (GTK_ENTRY (encode->frame_count), "0");
281 gtk_table_attach_defaults (GTK_TABLE (table), encode->frame_count, 1, 2, 5, 6);
282 gtk_widget_show (encode->frame_count);
285 frame = gtk_frame_new (_("Output file"));
286 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, FALSE, TRUE, 6);
287 gtk_widget_show (frame);
289 table = gtk_table_new (3, 2, TRUE);
290 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
291 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
292 gtk_container_set_border_width (GTK_CONTAINER (table), 6);
293 gtk_container_add (GTK_CONTAINER (frame), table);
294 gtk_widget_show (table);
296 label = gtk_label_new (_("Output path:"));
297 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
298 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
299 gtk_widget_show (label);
301 encode->path_output = gtk_file_chooser_button_new (_("Select a path"),
302 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
303 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (encode->path_output),
305 gtk_table_attach_defaults (GTK_TABLE (table), encode->path_output, 1, 2, 0, 1);
306 gtk_widget_show (encode->path_output);
308 label = gtk_label_new (_("Output file (without ext.):"));
309 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
310 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
311 gtk_widget_show (label);
313 encode->file_output = gtk_entry_new_with_max_length (4095);
314 gtk_table_attach_defaults (GTK_TABLE (table), encode->file_output, 1, 2, 1, 2);
315 gtk_widget_show (encode->file_output);
317 label = gtk_label_new (_("Container:"));
318 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
319 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
320 gtk_widget_show (label);
322 encode->combo = gtk_combo_box_new_text ();
323 gtk_combo_box_append_text (GTK_COMBO_BOX (encode->combo),
325 gtk_combo_box_append_text (GTK_COMBO_BOX (encode->combo),
328 gtk_combo_box_append_text (GTK_COMBO_BOX (encode->combo),
331 gtk_table_attach_defaults (GTK_TABLE (table), encode->combo, 1, 2, 2, 3);
332 gtk_widget_show (encode->combo);
334 gtk_combo_box_set_active (GTK_COMBO_BOX (encode->combo), 0);
336 gtk_widget_show (dialog);
342 x264_encode_shutdown (X264_Gtk_Encode *encode)
351 x264_delete_window_cb (GtkWidget *widget UNUSED,
352 GdkEvent *event UNUSED,
356 x264_encode_shutdown ((X264_Gtk_Encode *)user_data);
362 x264_chooser_window_cb (GtkDialog *dialog,
366 X264_Gtk_Encode *encode;
367 gboolean sensitivity = TRUE;
371 #define BUFFER_LENGTH 64
372 gchar buffer[BUFFER_LENGTH];
374 /* input interface */
375 int (*p_open_infile)( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param );
376 int (*p_get_frame_total)( hnd_t handle );
377 int (*p_close_infile)( hnd_t handle );
379 encode = (X264_Gtk_Encode *)user_data;
380 in = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (encode->file_input));
384 p_open_infile = open_file_yuv;
385 p_get_frame_total = get_frame_total_yuv;
386 p_close_infile = close_file_yuv;
387 param.i_width = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->width)), NULL));
388 param.i_height = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->height)), NULL));
389 param.i_fps_num = 25;
391 param.i_frame_total = 0;
394 case GTK_RESPONSE_OK:
395 case GTK_RESPONSE_ACCEPT:
396 case GTK_RESPONSE_APPLY: {
397 X264_Gtk_Encode *encode = (X264_Gtk_Encode *)user_data;
399 GtkFileFilter *selected;
402 filters = gtk_file_chooser_list_filters(GTK_FILE_CHOOSER (encode->file_input));
403 selected = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER (encode->file_input));
404 container = g_slist_index(filters, selected);
405 g_slist_free (filters);
409 /* All format needed, search for extension */
410 const char *ext = strrchr(in, '.');
411 if (!strncasecmp(ext, ".y4m", 4))
412 encode->container = X264_DEMUXER_Y4M;
413 else if (!strncasecmp(ext, ".avs", 4))
414 encode->container = X264_DEMUXER_AVS;
415 else if (!strncasecmp(ext, ".avi", 4))
416 encode->container = X264_DEMUXER_AVI;
417 else if (!strncasecmp(ext, ".cif", 4))
418 encode->container = X264_DEMUXER_CIF;
419 else if (!strncasecmp(ext, ".qcif", 4))
420 encode->container = X264_DEMUXER_QCIF;
422 encode->container = X264_DEMUXER_YUV;
426 /* The all supproted type is 0 => shift of 1 */
427 encode->container = (X264_Demuxer_Type)container-1;
430 switch (encode->container) {
431 case X264_DEMUXER_YUV: /* YUV */
433 case X264_DEMUXER_CIF: /* YUV CIF */
435 param.i_height = 288;
437 case X264_DEMUXER_QCIF: /* YUV QCIF */
438 /* Default input file driver */
440 param.i_height = 144;
442 case X264_DEMUXER_Y4M: /* YUV4MPEG */
443 /* Default input file driver */
445 p_open_infile = open_file_y4m;
446 p_get_frame_total = get_frame_total_y4m;
447 p_close_infile = close_file_y4m;
450 case X264_DEMUXER_AVI: /* AVI */
451 case X264_DEMUXER_AVS: /* AVS */
453 p_open_infile = open_file_avis;
454 p_get_frame_total = get_frame_total_avis;
455 p_close_infile = close_file_avis;
458 default: /* Unknown */
468 gtk_widget_set_sensitive(encode->width, sensitivity);
469 gtk_widget_set_sensitive(encode->height, sensitivity);
470 gtk_widget_set_sensitive(encode->fps_num, sensitivity);
471 gtk_widget_set_sensitive(encode->fps_den, sensitivity);
472 gtk_widget_set_sensitive(encode->frame_count, sensitivity);
474 /* Inquire input format */
475 if (param.i_width < 2) param.i_width = 352;
476 if (param.i_height < 2) param.i_height = 288;
477 if (p_open_infile (in, &hin, ¶m) >= 0) {
478 param.i_frame_total = p_get_frame_total(hin);
479 p_close_infile (hin);
481 GtkWidget *dialog_message;
483 dialog_message = gtk_message_dialog_new (GTK_WINDOW (dialog),
484 GTK_DIALOG_DESTROY_WITH_PARENT,
488 gtk_dialog_run (GTK_DIALOG (dialog_message));
489 gtk_widget_destroy (dialog_message);
491 encode->size = x264_file_size(in);
493 if (g_snprintf(buffer, BUFFER_LENGTH, "%i", param.i_width) > 0)
494 gtk_entry_set_text (GTK_ENTRY (encode->width), buffer);
495 if (g_snprintf(buffer, BUFFER_LENGTH, "%i", param.i_height) > 0)
496 gtk_entry_set_text (GTK_ENTRY (encode->height), buffer);
497 if (g_snprintf(buffer, BUFFER_LENGTH, "%i", param.i_fps_num) > 0)
498 gtk_entry_set_text (GTK_ENTRY (encode->fps_num), buffer);
499 if (g_snprintf(buffer, BUFFER_LENGTH, "%i", param.i_fps_den) > 0)
500 gtk_entry_set_text (GTK_ENTRY (encode->fps_den), buffer);
502 if (g_snprintf(buffer, BUFFER_LENGTH, "%i", param.i_frame_total) > 0)
503 gtk_entry_set_text (GTK_ENTRY (encode->frame_count), buffer);
506 x264_dimension_entry_cb (GtkEditable *editable,
509 X264_Gtk_Encode *encode = (X264_Gtk_Encode *)user_data;
515 width = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->width)), NULL));
516 height = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->height)), NULL));
517 frame_size = (3*width*height)/2;
519 if (frame_size > 0 && encode->container <= X264_DEMUXER_QCIF)
521 snprintf(buffer, 32, "%lu", (long unsigned int)((encode->size+frame_size/2)/frame_size));
522 gtk_entry_set_text (GTK_ENTRY (encode->frame_count), buffer);
527 x264_configure_window_cb (GtkButton *button UNUSED,
532 window = x264_gtk_window_create (GTK_WIDGET (user_data));
533 x264_gtk_shutdown (window);
537 x264_response_window_cb (GtkDialog *dialog,
542 case GTK_RESPONSE_APPLY: {
545 X264_Gtk_Encode *encode;
546 X264_Thread_Data *thread_data;
547 GtkWidget *win_status;
549 const gchar *file_input = NULL;
550 const gchar *path_output = NULL;
551 const gchar *filename_output = NULL;
552 gchar *file_output = NULL;
557 encode = (X264_Gtk_Encode *)user_data;
558 file_input = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (encode->file_input));
559 path_output = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (encode->path_output));
560 filename_output = gtk_entry_get_text (GTK_ENTRY (encode->file_output));
563 (file_input[0] == '\0')) {
564 GtkWidget *dialog_message;
566 dialog_message = gtk_message_dialog_new (GTK_WINDOW (dialog),
567 GTK_DIALOG_DESTROY_WITH_PARENT,
570 _("Error: input file name is not set"));
571 gtk_dialog_run (GTK_DIALOG (dialog_message));
572 gtk_widget_destroy (dialog_message);
576 if (!filename_output ||
577 (filename_output[0] == '\0')) {
578 GtkWidget *dialog_message;
580 dialog_message = gtk_message_dialog_new (GTK_WINDOW (dialog),
581 GTK_DIALOG_DESTROY_WITH_PARENT,
584 _("Error: output file name is not set"));
585 gtk_dialog_run (GTK_DIALOG (dialog_message));
586 gtk_widget_destroy (dialog_message);
590 out_container = gtk_combo_box_get_active (GTK_COMBO_BOX (encode->combo));
592 switch (out_container) {
606 file_output = g_strconcat (path_output, "/", filename_output, ext, NULL);
607 g_print (_("file output : %s\n"), file_output);
612 file = g_io_channel_new_file (file_output, "r", NULL);
614 GtkWidget *dialog_overwrite;
617 const gchar *label_text = NULL;
620 dialog_overwrite = gtk_dialog_new_with_buttons (_("Existing file"),
622 GTK_DIALOG_DESTROY_WITH_PARENT,
629 eb = gtk_event_box_new ();
630 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog_overwrite)->vbox), eb);
631 gtk_container_set_border_width (GTK_CONTAINER (eb), 6);
632 gtk_widget_show (eb);
634 label_text = g_strconcat (_("Do you want to overwrite file\n"),
635 file_output, " ?", NULL);
636 label = gtk_label_new (label_text);
637 gtk_container_add (GTK_CONTAINER (eb), label);
638 gtk_widget_show (label);
640 res = gtk_dialog_run (GTK_DIALOG (dialog_overwrite));
641 gtk_widget_destroy (dialog_overwrite);
642 g_io_channel_unref (file);
643 if ((res == GTK_RESPONSE_REJECT) || (res == GTK_RESPONSE_DELETE_EVENT))
648 x264_gtk = x264_gtk_load ();
649 param = x264_gtk_param_get (x264_gtk);
650 x264_gtk_free (x264_gtk);
659 width = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->width)), NULL));
660 height = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->height)), NULL));
661 fps_num = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->fps_num)), NULL));
662 fps_den = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->fps_den)), NULL));
663 frame_count = (gint)(g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (encode->frame_count)), NULL));
672 param->i_width = width;
673 param->i_height = height;
674 param->i_fps_num = fps_num;
675 param->i_fps_den = fps_den;
676 param->i_frame_total = frame_count;
679 if (pipe (fds) == -1)
682 thread_data = (X264_Thread_Data *)g_malloc0 (sizeof (X264_Thread_Data));
683 thread_data->param = param;
684 thread_data->file_input = g_strdup (file_input);
685 thread_data->file_output = g_strdup (file_output);
686 thread_data->in_container = encode->container;
687 thread_data->out_container = out_container;
688 g_free (file_output);
690 thread_data->io_read = g_io_channel_unix_new (fds[0]);
691 g_io_channel_set_encoding (thread_data->io_read, NULL, NULL);
692 thread_data->io_write = g_io_channel_unix_new (fds[1]);
693 g_io_channel_set_encoding (thread_data->io_write, NULL, NULL);
695 g_io_add_watch (thread_data->io_read, G_IO_IN,
696 (GIOFunc)x264_fill_status_window, thread_data);
698 win_status = x264_gtk_encode_status_window (thread_data);
699 gtk_window_set_transient_for (GTK_WINDOW (win_status), GTK_WINDOW (dialog));
700 gtk_window_set_modal (GTK_WINDOW (win_status), TRUE);
701 gtk_widget_show (win_status);
702 //gtk_widget_hide(thread_data->end_button);
704 thread = g_thread_create ((GThreadFunc)x264_gtk_encode_encode, thread_data, FALSE, NULL);
708 case GTK_RESPONSE_CLOSE:
711 x264_encode_shutdown ((X264_Gtk_Encode *)user_data);
716 x264_fill_status_window (GIOChannel *io UNUSED,
717 GIOCondition condition UNUSED,
721 X264_Thread_Data *thread_data;
722 X264_Pipe_Data pipe_data;
729 thread_data = (X264_Thread_Data *)user_data;
730 status = g_io_channel_read_chars (thread_data->io_read,
732 sizeof (X264_Pipe_Data),
734 if (status != G_IO_STATUS_NORMAL) {
735 g_print (_("Error ! %d %d %d\n"), status, (int)sizeof (X264_Pipe_Data), (int)size);
739 snprintf (str, 128, "%d/%d", pipe_data.frame, pipe_data.frame_total);
740 gtk_entry_set_text (GTK_ENTRY (thread_data->current_video_frame),
743 snprintf (str, 128, _("%dKB"),
744 pipe_data.file >> 10);
745 gtk_entry_set_text (GTK_ENTRY (thread_data->video_data),
748 fps = pipe_data.elapsed > 0 ? 1000000.0 * (gdouble)pipe_data.frame / (gdouble)pipe_data.elapsed : 0.0;
749 snprintf (str, 128, _("%.2fKB/s (%.2f fps)"),
750 (double) pipe_data.file * 8 * thread_data->param->i_fps_num /
751 ((double) thread_data->param->i_fps_den * pipe_data.frame * 1000),
753 gtk_entry_set_text (GTK_ENTRY (thread_data->video_rendering_rate),
756 snprintf (str, 128, "%lld:%02lld:%02lld",
757 (pipe_data.elapsed / 1000000) / 3600,
758 ((pipe_data.elapsed / 1000000) / 60) % 60,
759 (pipe_data.elapsed / 1000000) % 60);
760 gtk_entry_set_text (GTK_ENTRY (thread_data->time_elapsed),
763 eta = pipe_data.elapsed * (pipe_data.frame_total - pipe_data.frame) / ((int64_t)pipe_data.frame * 1000000);
764 snprintf (str, 128, "%d:%02d:%02d", eta / 3600, (eta / 60) % 60, eta % 60);
765 gtk_entry_set_text (GTK_ENTRY (thread_data->time_remaining),
768 progress = (gdouble)pipe_data.frame / (gdouble)pipe_data.frame_total;
769 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (thread_data->progress),
772 snprintf (str, 128, "%0.1f%%", 100.0 * progress);
773 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (thread_data->progress), str);