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
+ifeq ($(SYS),MINGW)
+datadir=.
+OBJECTS+=x264gtk.o
+LDFLAGS+=-mwindows
+else
+datadir=${prefix}/share/x264
+endif
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
+LDFLAGS += `pkg-config --libs gtk+-2.0 gthread-2.0 x264`
# Compilation rule
%.o : %.c
@echo " C: $(@D)/$(<F)"
@$(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
+%.o : %.rc
+ @echo " C: $(@D)/$(<F)"
+ @windres -o $@ -i $<
+
+x264_icon.h: x264.ico
+ @gdk-pixbuf-csource --name=x264_icon --stream x264.ico > x264_icon.h
# Linking rule
libx264gtk.a: $(OBJECTS)
@echo " B: $(@F)"
@$(CC) -o test $(OBJECTS) $(TEST_OBJECT) $(LDFLAGS)
-x264_gtk_encode: $(OBJECTS) libx264gtk.a $(ENCODE_OBJECT)
+x264_gtk_encode: $(OBJECTS) x264_icon.h 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
+ @rm -f *.o test x264_gtk_encode libx264gtk.a x264_icon.h
# Install rule
install: 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
+x264gtk.o: x264_gtk.h x264gtk.rc x264.ico x264_gtk_bitrate.h x264_gtk_bitrate.o x264_gtk_rc.h x264_gtk_rc.o x264_gtk_mb.h x264_gtk_mb.o x264_gtk_more.h x264_gtk_more.o
+x264_gtk_bitrate.o: x264_gtk_private.h x264_gtk_enum.h x264_gtk_bitrate.c
+x264_gtk_rc.o: x264_gtk_private.h x264_gtk_rc.c
+x264_gtk_mb.o: x264_gtk_private.h x264_gtk_mb.c
+x264_gtk_more.o: x264_gtk_private.h x264_gtk_more.c
+x264_gtk_encode_encode.o: x264_gtk_encode_private.h x264_gtk_encode_encode.c
+x264_gtk_encode_status_window.o: x264_gtk_encode_private.h x264_gtk_encode_status_window.c
+x264_gtk_encode_main_window.o: x264_gtk_encode_private.h x264_gtk_encode_encode.o x264_gtk_encode_status_window.o x264_gtk.o x264_gtk_encode_main_window.c
+x264_gtk_encode.o: x264_gtk_encode_main_window.o x264_gtk_encode.c
test.o: x264_gtk.o test.c
#include <gtk/gtk.h>
+#include "../config.h"
#include "../x264.h"
#include "../muxers.h"
#include "x264_gtk_encode_private.h"
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 );
+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_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);
+static int _set_drivers (gint int_container, gint out_container);
+static int _encode_frame (x264_t *h, void *handle, x264_picture_t *pic);
gpointer
int64_t i_file;
int i_frame_size;
int i_progress;
+ int err;
g_print ("encoding...\n");
param = thread_data->param;
- _set_drivers (thread_data->container);
-
+ err = _set_drivers (thread_data->in_container, thread_data->out_container);
+ if (err < 0) {
+ GtkWidget *no_driver;
+ no_driver = gtk_message_dialog_new (GTK_WINDOW(thread_data->dialog),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ (err == -2) ? "Error: unknown output file type"
+ : "Error: unknown input file type");
+ gtk_dialog_run (GTK_DIALOG (no_driver));
+ gtk_widget_destroy (no_driver);
+ return NULL;
+ }
+
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;
(double) i_file * 8 * param->i_fps_num /
((double) param->i_fps_den * i_frame * 1000));
}
+
+ gtk_widget_set_sensitive (thread_data->end_button, TRUE);
+ gtk_widget_hide (thread_data->button);
return NULL;
}
-static void
-_set_drivers (gint container)
+static int
+_set_drivers (gint in_container, gint out_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 (in_container) {
+ case 0: /* YUV */
+ case 1: /* CIF */
+ case 2: /* QCIF */
+ /* 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;
+ break;
+#ifdef AVIS_INPUT
+ case 3: /* AVI */
+ case 4: /* AVS */
+ p_open_infile = open_file_avis;
+ p_get_frame_total = get_frame_total_avis;
+ p_read_frame = read_frame_avis;
+ p_close_infile = close_file_avis;
+ break;
+#endif
+ default: /* Unknown */
+ return -1;
+ }
- switch (container) {
+ switch (out_container) {
case 0:
/* Raw ES output file driver */
p_open_outfile = open_file_bsf;
p_close_outfile = close_file_mp4;
break;
#endif
+ default:
+ return -2;
}
+
+ return 1;
}
static int
# include <stdint.h>
#endif
#include <unistd.h>
+#ifdef _WIN32 /* Needed to define _O_BINARY */
+# include <fcntl.h>
+#endif
#include <gtk/gtk.h>
#include "../x264.h"
+#include "../config.h"
+#include "../muxers.h"
+#include "x264_icon.h"
#include "x264_gtk.h"
#include "x264_gtk_encode_private.h"
#include "x264_gtk_encode_encode.h"
GtkWidget *main_dialog;
/* input */
+ gint container;
GtkWidget *file_input;
GtkWidget *width;
GtkWidget *height;
gpointer user_data);
static void _configure_window_cb (GtkButton *button,
gpointer user_data);
+static void _chooser_window_cb (GtkDialog *dialog,
+ gint res,
+ gpointer user_data);
static void _response_window_cb (GtkDialog *dialog,
gint res,
gpointer user_data);
GIOCondition condition,
gpointer user_data);
/* Code */
-
void
x264_gtk_encode_main_window ()
{
GtkWidget *button;
GtkWidget *table;
GtkWidget *label;
+ GtkFileChooser *chooser;
GtkFileFilter *filter;
+ GdkPixbuf *icon;
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);
+ icon = gdk_pixbuf_new_from_inline (-1, x264_icon,
+ FALSE, NULL);
+ gtk_window_set_icon (GTK_WINDOW (dialog), icon);
g_signal_connect (G_OBJECT (dialog),
"delete-event",
G_CALLBACK (_delete_window_cb),
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 ());
+ chooser = (GtkFileChooser*)
+ gtk_file_chooser_dialog_new("Select a file",
+ GTK_WINDOW(dialog),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_file_chooser_set_current_folder (chooser, g_get_home_dir ());
+ /* All supported */
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, "All supported");
+ gtk_file_filter_add_pattern (filter, "*.yuv");
+ gtk_file_filter_add_pattern (filter, "*.cif");
+ gtk_file_filter_add_pattern (filter, "*.qcif");
+#ifdef AVIS_INPUT
+ gtk_file_filter_add_pattern (filter, "*.avs");
+ gtk_file_filter_add_pattern (filter, "*.avi");
+#endif
+ gtk_file_chooser_add_filter (chooser, filter);
+ /* YUV filter */
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, "YUV sequence");
+ gtk_file_filter_add_pattern (filter, "*.yuv");
+ gtk_file_chooser_add_filter (chooser, filter);
+
+ /* CIF filter */
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_file_filter_set_name (filter, "YUV CIF sequence");
+ gtk_file_filter_add_pattern (filter, "*.cif");
+ gtk_file_chooser_add_filter (chooser, filter);
+
+ /* CIF filter */
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, "YUV QCIF sequence");
+ gtk_file_filter_add_pattern (filter, "*.qcif");
+ gtk_file_chooser_add_filter (chooser, filter);
+
+#ifdef AVIS_INPUT
+ /* AVI filter */
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, "AVI");
+ gtk_file_filter_add_pattern (filter, "*.avi");
+ gtk_file_chooser_add_filter (chooser, filter);
+ /* AVS filter */
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, "Avisynth Script");
+ gtk_file_filter_add_pattern (filter, "*.avs");
+ gtk_file_chooser_add_filter (chooser, filter);
+#endif
+ g_signal_connect_after(G_OBJECT (chooser), "response",
+ G_CALLBACK (_chooser_window_cb),
+ encode);
+ encode->file_input = gtk_file_chooser_button_new_with_dialog(GTK_WIDGET(chooser));
gtk_table_attach_defaults (GTK_TABLE (table), encode->file_input, 1, 2, 0, 1);
gtk_widget_show (encode->file_input);
return TRUE;
}
+static void
+_chooser_window_cb (GtkDialog *dialog,
+ gint res,
+ gpointer user_data)
+{
+ X264_Gtk_Encode *encode;
+ gboolean sensitivity = FALSE;
+ x264_param_t param;
+ char *in;
+#define BUFFER_LENGTH 64
+ gchar buffer[BUFFER_LENGTH];
+
+
+ /* 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_close_infile)( hnd_t handle );
+
+ encode = (X264_Gtk_Encode *)user_data;
+ if (!encode || !encode->file_input) return;
+ in = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (encode->file_input));
+ if (!in) return;
+
+ /* Set defaults */
+ param.i_width = 352;
+ param.i_height = 288;
+ param.i_fps_num = 25;
+ param.i_fps_den = 1;
+ param.i_frame_total = 0;
+
+ switch (res) {
+ case GTK_RESPONSE_OK:
+ case GTK_RESPONSE_ACCEPT:
+ case GTK_RESPONSE_APPLY: {
+ X264_Gtk_Encode *encode = (X264_Gtk_Encode *)user_data;
+ GSList *filters;
+ GtkFileFilter *selected;
+
+ filters = gtk_file_chooser_list_filters(GTK_FILE_CHOOSER (encode->file_input));
+ selected = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER (encode->file_input));
+ encode->container = g_slist_index(filters, selected);
+ g_slist_free (filters);
+
+ switch (encode->container) {
+ case 0: /* YUV */
+ case 1: /* CIF */
+ case 2: /* QCIF */
+ /* Default input file driver */
+ sensitivity = TRUE;
+ p_open_infile = open_file_yuv;
+ p_get_frame_total = get_frame_total_yuv;
+ p_close_infile = close_file_yuv;
+ break;
+#ifdef AVIS_INPUT
+ case 3: /* AVI */
+ case 4: /* AVS */
+ p_open_infile = open_file_avis;
+ p_get_frame_total = get_frame_total_avis;
+ p_close_infile = close_file_avis;
+ break;
+#endif
+ default: /* Unknown */
+ sensitivity = TRUE;
+ }
+ break;
+ }
+ default:
+ sensitivity = TRUE;
+ }
+
+ /* Modify dialog */
+ gtk_widget_set_sensitive(encode->width, sensitivity);
+ gtk_widget_set_sensitive(encode->height, sensitivity);
+ gtk_widget_set_sensitive(encode->fps_num, sensitivity);
+ gtk_widget_set_sensitive(encode->fps_den, sensitivity);
+ gtk_widget_set_sensitive(encode->frame_count, sensitivity);
+
+ if (sensitivity == FALSE && encode->container > 2 /* QCIF */) {
+ /* Inquire input format */
+ hnd_t hin;
+
+ p_open_infile (in, &hin, ¶m);
+ param.i_frame_total = p_get_frame_total(hin);
+ p_close_infile (hin);
+ }
+ if (g_snprintf(buffer, BUFFER_LENGTH, "%i", param.i_width) > 0)
+ gtk_entry_set_text (GTK_ENTRY (encode->width), buffer);
+ if (g_snprintf(buffer, BUFFER_LENGTH, "%i", param.i_height) > 0)
+ gtk_entry_set_text (GTK_ENTRY (encode->height), buffer);
+ if (g_snprintf(buffer, BUFFER_LENGTH, "%i", param.i_fps_num) > 0)
+ gtk_entry_set_text (GTK_ENTRY (encode->fps_num), buffer);
+ if (g_snprintf(buffer, BUFFER_LENGTH, "%i", param.i_fps_den) > 0)
+ gtk_entry_set_text (GTK_ENTRY (encode->fps_den), buffer);
+
+ if (g_snprintf(buffer, BUFFER_LENGTH, "%i", param.i_frame_total) > 0)
+ gtk_entry_set_text (GTK_ENTRY (encode->frame_count), buffer);
+}
+
static void
_configure_window_cb (GtkButton *button __UNUSED__,
gpointer user_data)
gchar *file_output = NULL;
gchar *ext;
gint fds[2];
- gint container;
+ gint out_container;
encode = (X264_Gtk_Encode *)user_data;
file_input = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (encode->file_input));
GtkWidget *dialog_message;
dialog_message = gtk_message_dialog_new (GTK_WINDOW (dialog),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
+ 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;
break;
}
- container = gtk_combo_box_get_active (GTK_COMBO_BOX (encode->combo));
+ out_container = gtk_combo_box_get_active (GTK_COMBO_BOX (encode->combo));
- switch (container) {
- case 0:
- ext = ".264";
- break;
+ switch (out_container) {
case 1:
ext = ".mkv";
break;
ext = ".mp4";
break;
#endif
+ case 0:
default:
ext = ".264";
}
thread_data->param = param;
thread_data->file_input = g_strdup (file_input);
thread_data->file_output = g_strdup (file_output);
- thread_data->container = container;
+ thread_data->in_container = encode->container;
+ thread_data->out_container = out_container;
g_free (file_output);
thread_data->io_read = g_io_channel_unix_new (fds[0]);
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);
+ //gtk_widget_hide(thread_data->end_button);
thread = g_thread_create ((GThreadFunc)x264_gtk_encode_encode, thread_data, FALSE, NULL);