diff options
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/src/callbacks.c | 14 | ||||
-rw-r--r-- | gtk/src/ghb.ui | 1111 | ||||
-rw-r--r-- | gtk/src/hb-backend.c | 227 | ||||
-rw-r--r-- | gtk/src/internal_defaults.xml | 20 | ||||
-rw-r--r-- | gtk/src/main.c | 12 | ||||
-rw-r--r-- | gtk/src/makedeps.py | 4 | ||||
-rw-r--r-- | gtk/src/presets.c | 137 | ||||
-rw-r--r-- | gtk/src/settings.c | 2 | ||||
-rw-r--r-- | gtk/src/x264handler.c | 232 | ||||
-rw-r--r-- | gtk/src/x264handler.h | 1 |
10 files changed, 1341 insertions, 419 deletions
diff --git a/gtk/src/callbacks.c b/gtk/src/callbacks.c index 29c767c17..a37771a86 100644 --- a/gtk/src/callbacks.c +++ b/gtk/src/callbacks.c @@ -79,6 +79,7 @@ #include "hb-backend.h" #include "ghb-dvd.h" #include "ghbcellrenderertext.h" +#include "x264handler.h" static void reset_chapter_list(signal_user_data_t *ud, GValue *settings); static void update_chapter_list_from_settings(GtkBuilder *builder, GValue *settings); @@ -3757,7 +3758,7 @@ ghb_hbfd(signal_user_data_t *ud, gboolean hbfd) set_visible(widget, !hbfd); widget = GHB_WIDGET(ud->builder, "container_box"); set_visible(widget, !hbfd); - widget = GHB_WIDGET(ud->builder, "settings_box"); + widget = GHB_WIDGET(ud->builder, "SettingsNotebook"); set_visible(widget, !hbfd); widget = GHB_WIDGET(ud->builder, "presets_save"); set_visible(widget, !hbfd); @@ -3790,6 +3791,17 @@ advanced_audio_changed_cb(GtkWidget *widget, signal_user_data_t *ud) } G_MODULE_EXPORT void +advanced_video_changed_cb(GtkWidget *widget, signal_user_data_t *ud) +{ + g_debug("advanced_video_changed_cb"); + ghb_widget_to_setting (ud->settings, widget); + ghb_check_dependency(ud, widget, NULL); + const gchar *name = ghb_get_setting_key(widget); + ghb_pref_save(ud->settings, name); + ghb_show_hide_advanced_video( ud ); +} + +G_MODULE_EXPORT void pref_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { g_debug("pref_changed_cb"); diff --git a/gtk/src/ghb.ui b/gtk/src/ghb.ui index b5ca17ca2..9aca658ff 100644 --- a/gtk/src/ghb.ui +++ b/gtk/src/ghb.ui @@ -121,6 +121,14 @@ <property name="page_size">0</property> <property name="value">20.25</property> </object> + <object class="GtkAdjustment" id="x264PresetRange"> + <property name="upper">1</property> + <property name="lower">0</property> + <property name="page_increment">1</property> + <property name="step_increment">1</property> + <property name="page_size">0</property> + <property name="value">0</property> + </object> <object class="GtkAdjustment" id="adjustment8"> <property name="upper">16</property> <property name="lower">1</property> @@ -1231,7 +1239,7 @@ <property name="right_padding">12</property> <child> - <object class="GtkNotebook" id="settings_box"> + <object class="GtkNotebook" id="SettingsNotebook"> <property name="visible">True</property> <property name="can_focus">True</property> <child> @@ -1764,25 +1772,29 @@ </packing> </child> <child> - <object class="GtkHBox" id="hbox17"> + <object class="GtkVBox" id="vbox22"> <property name="visible">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="spacing">48</property> + <property name="spacing">8</property> <child> - <object class="GtkAlignment" id="alignment14"> + <object class="GtkHBox" id="hbox17"> <property name="visible">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="top_padding">48</property> - <property name="left_padding">24</property> + + <property name="spacing">48</property> <child> - <object class="GtkVBox" id="vbox13"> - <property name="orientation">vertical</property> + <object class="GtkAlignment" id="alignment14"> <property name="visible">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="spacing">4</property> + <property name="top_padding">8</property> + <property name="left_padding">24</property> <child> - <object class="GtkHBox" id="hbox18"> + <object class="GtkTable" id="table15"> + <property name="row_spacing">5</property> + <property name="column_spacing">5</property> + <property name="n_rows">6</property> + <property name="n_columns">2</property> <property name="visible">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <child> @@ -1790,281 +1802,587 @@ <property name="visible">True</property> <property name="xalign">0</property> <property name="label" translatable="yes">Video Encoder:</property> - <property name="width_chars">11</property> </object> <packing> - <property name="expand">False</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL|GTK_EXPAND</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="VideoEncoder"> + <property name="visible">True</property> + <property name="tooltip-text" translatable="yes">Available video encoders.</property> + <signal handler="vcodec_changed_cb" name="changed"/> + </object> + <packing> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL|GTK_EXPAND</property> </packing> </child> <child> - <object class="GtkAlignment" id="alignment11"> + <object class="GtkLabel" id="label47"> <property name="visible">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="xalign">0</property> - <property name="xscale">0</property> - <child> - <object class="GtkComboBox" id="VideoEncoder"> - <property name="visible">True</property> - <property name="tooltip-text" translatable="yes">Available video encoders.</property> - <signal handler="vcodec_changed_cb" name="changed"/> - </object> - </child> + <property name="label" translatable="yes">Framerate:</property> </object> <packing> - <property name="padding">4</property> - <property name="position">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL|GTK_EXPAND</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="VideoFramerate"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Output framerate. 'Same as source' is recommended. If your source video has a variable framerate, 'Same as source' will preserve it.</property> + <signal handler="framerate_changed_cb" name="changed"/> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL|GTK_EXPAND</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="VideoFramerateCFR"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Enables constant framerate output.</property> + <property name="label" translatable="yes">Constant Framerate</property> + <property name="draw_indicator">True</property> + <signal handler="setting_widget_changed_cb" name="toggled"/> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="left_attach">0</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL|GTK_EXPAND</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="VideoFrameratePFR"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Enables variable framerate output with a peak rate determined by the framerate setting. VFR is not compatible with some players.</property> + <property name="label" translatable="yes">Peak Framerate (VFR)</property> + <property name="draw_indicator">True</property> + <property name="group">VideoFramerateCFR</property> + <signal handler="setting_widget_changed_cb" name="toggled"/> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="left_attach">0</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL|GTK_EXPAND</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="VideoFramerateVFR"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Enables variable framerate output. VFR is not compatible with some players.</property> + <property name="label" translatable="yes">Variable Framerate</property> + <property name="draw_indicator">True</property> + <property name="group">VideoFramerateCFR</property> + <signal handler="setting_widget_changed_cb" name="toggled"/> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="left_attach">0</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL|GTK_EXPAND</property> </packing> </child> </object> - <packing> - <property name="expand">False</property> - </packing> </child> + </object> + <packing> + <property name="expand">False</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="alignment10"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="top_padding">48</property> + <property name="right_padding">24</property> <child> - <object class="GtkHBox" id="hbox19"> + <object class="GtkTable" id="table8"> + <property name="row_spacing">5</property> + <property name="column_spacing">5</property> + <property name="n_rows">6</property> + <property name="n_columns">3</property> <property name="visible">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <child> - <object class="GtkLabel" id="label47"> + <object class="GtkHScale" id="VideoQualitySlider"> <property name="visible">True</property> + <property name="can_focus">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Framerate:</property> - <property name="width_chars">11</property> + <property name="tooltip-text" translatable="yes">Set the desired quality factor. The encoder targets a certain quality. The scale used by each video encoder is different. + + x264's scale is logarithmic and lower values coorespond to higher quality. So small decreases in value will result in progressively larger increases in the resulting file size. A value of 0 means lossless and will result in a file size that is larger than the original source, unless the source was also lossless. + + FFMpeg's and Theora's scale is more linear. These encoders do not have a lossless mode.</property> + <property name="adjustment">adjustment5</property> + <property name="digits">3</property> + <property name="value_pos">GTK_POS_TOP</property> + <signal handler="vquality_changed_cb" name="value_changed"/> + <signal handler="format_vquality_cb" name="format-value"/> </object> <packing> - <property name="expand">False</property> + <property name="left_attach">0</property> + <property name="right_attach">3</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL|GTK_EXPAND</property> </packing> </child> <child> - <object class="GtkAlignment" id="alignment12"> + <object class="GtkRadioButton" id="vquality_type_constant"> <property name="visible">True</property> + <property name="can_focus">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="xalign">0</property> - <property name="xscale">0</property> + <property name="tooltip-text" translatable="yes">Set the desired quality factor. The encoder targets a certain quality. The scale used by each video encoder is different. + + x264's scale is logarithmic and lower values coorespond to higher quality. So small decreases in value will result in progressively larger increases in the resulting file size. A value of 0 means lossless and will result in a file size that is larger than the original source, unless the source was also lossless. + + FFMpeg's and Theora's scale is more linear. These encoders do not have a lossless mode.</property> + <property name="label" translatable="yes">Constant Quality:</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + <signal handler="setting_widget_changed_cb" name="toggled"/> + </object> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options"></property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="vquality_type_bitrate"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Set the average bitrate. The instantaneous bitrate can be much higher or lower at any point in time. But the average over a long duration will be the value set here. If you need to limit instantaneous bitrate, look into x264's vbv-bufsize and vbv-maxrate settings.</property> + <property name="label" translatable="yes">Bitrate (kbps): </property> + <property name="group">vquality_type_constant</property> + <property name="draw_indicator">True</property> + <signal handler="setting_widget_changed_cb" name="toggled"/> + </object> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="VideoAvgBitrate"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Set the average bitrate. The instantaneous bitrate can be much higher or lower at any point in time. But the average over a long duration will be the value set here. If you need to limit instantaneous bitrate, look into x264 vbv-bufsize and vbv-maxrate.</property> + <property name="adjustment">adjustment3</property> + <signal handler="setting_widget_changed_cb" name="value_changed"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> + <property name="x_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="VideoTwoPass"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Perform 2 Pass Encoding. The 'Bitrate' option is prerequisite. During the 1st pass, statistics about the video are collected. Then in the second pass, those statistics are used to make bitrate allocation decisions.</property> + <property name="label" translatable="yes">2-Pass Encoding</property> + <property name="draw_indicator">True</property> + <signal handler="setting_widget_changed_cb" name="toggled"/> + </object> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="alignment13"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="left_padding">16</property> <child> - <object class="GtkComboBox" id="VideoFramerate"> + <object class="GtkCheckButton" id="VideoTurboTwoPass"> <property name="visible">True</property> + <property name="can_focus">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip-text" translatable="yes">Output framerate. 'Same as source' is recommended. If your source video has a variable framerate, 'Same as source' will preserve it.</property> - <signal handler="framerate_changed_cb" name="changed"/> + <property name="tooltip-text" translatable="yes">During the 1st pass of a 2 pass encode, use settings that speed things along.</property> + <property name="label" translatable="yes">Turbo First Pass</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + <signal handler="setting_widget_changed_cb" name="toggled"/> </object> </child> </object> <packing> - <property name="padding">4</property> - <property name="position">1</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> </packing> </child> </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="VideoFramerateCFR"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip-text" translatable="yes">Enables constant framerate output.</property> - <property name="label" translatable="yes">Constant Framerate</property> - <property name="draw_indicator">True</property> - <signal handler="setting_widget_changed_cb" name="toggled"/> - </object> - <packing> - <property name="expand">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="VideoFrameratePFR"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip-text" translatable="yes">Enables variable framerate output with a peak rate determined by the framerate setting. VFR is not compatible with some players.</property> - <property name="label" translatable="yes">Peak Framerate (VFR)</property> - <property name="draw_indicator">True</property> - <property name="group">VideoFramerateCFR</property> - <signal handler="setting_widget_changed_cb" name="toggled"/> - </object> - <packing> - <property name="expand">False</property> - <property name="position">3</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="VideoFramerateVFR"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip-text" translatable="yes">Enables variable framerate output. VFR is not compatible with some players.</property> - <property name="label" translatable="yes">Variable Framerate</property> - <property name="draw_indicator">True</property> - <property name="group">VideoFramerateCFR</property> - <signal handler="setting_widget_changed_cb" name="toggled"/> - </object> - <packing> - <property name="expand">False</property> - <property name="position">4</property> - </packing> </child> </object> + <packing> + <property name="padding">2</property> + <property name="position">1</property> + <property name="expand">False</property> + </packing> </child> </object> <packing> + <property name="padding">2</property> + <property name="position">0</property> <property name="expand">False</property> </packing> </child> <child> - <object class="GtkAlignment" id="alignment10"> + <object class="GtkAlignment" id="alignment55"> <property name="visible">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="top_padding">48</property> + <property name="left_padding">24</property> <property name="right_padding">24</property> <child> - <object class="GtkTable" id="table8"> - <property name="n_rows">6</property> - <property name="n_columns">3</property> + <object class="GtkVBox" id="x264VideoSettings"> + <property name="orientation">vertical</property> <property name="visible">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <child> - <object class="GtkHScale" id="VideoQualitySlider"> + <object class="GtkCheckButton" id="x264UseAdvancedOptions"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip-text" translatable="yes">Set the desired quality factor. The encoder targets a certain quality. The scale used by each video encoder is different. + <property name="tooltip-text" translatable="yes">Use advanced options Tab for x264 settings. -x264's scale is logarithmic and lower values coorespond to higher quality. So small decreases in value will result in progressively larger increases in the resulting file size. A value of 0 means lossless and will result in a file size that is larger than the original source, unless the source was also lossless. - -FFMpeg's and Theora's scale is more linear. These encoders do not have a lossless mode.</property> - <property name="adjustment">adjustment5</property> - <property name="digits">3</property> - <property name="value_pos">GTK_POS_TOP</property> - <signal handler="vquality_changed_cb" name="value_changed"/> - <signal handler="format_vquality_cb" name="format-value"/> +Use at your own risk!</property> + <property name="label" translatable="yes">Use Advanced Options</property> + <property name="active">False</property> + <property name="draw_indicator">True</property> + <signal handler="x264_use_advanced_options_changed_cb" name="toggled"/> </object> <packing> - <property name="left_attach">0</property> - <property name="right_attach">3</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_options">GTK_FILL</property> - <property name="x_options">GTK_FILL|GTK_EXPAND</property> + <property name="expand">True</property> + <property name="padding">2</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkRadioButton" id="vquality_type_constant"> + <object class="GtkTable" id="x264VideoSettingsTable"> + <property name="row_spacing">5</property> + <property name="column_spacing">5</property> + <property name="n_rows">4</property> + <property name="n_columns">6</property> <property name="visible">True</property> - <property name="can_focus">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip-text" translatable="yes">Set the desired quality factor. The encoder targets a certain quality. The scale used by each video encoder is different. + <child> + <object class="GtkLabel" id="x264PresetLabel"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">x264 Preset:</property> + </object> + <packing> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkHScale" id="x264PresetSlider"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Adjusts x264 settings to trade off compression efficiency against encoding speed. -x264's scale is logarithmic and lower values coorespond to higher quality. So small decreases in value will result in progressively larger increases in the resulting file size. A value of 0 means lossless and will result in a file size that is larger than the original source, unless the source was also lossless. + This establishes your default x264 settings. Tunes, profiles, levels and advanced option string will be applied to this. -FFMpeg's and Theora's scale is more linear. These encoders do not have a lossless mode.</property> - <property name="label" translatable="yes">Constant Quality:</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - <signal handler="setting_widget_changed_cb" name="toggled"/> - </object> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkRadioButton" id="vquality_type_bitrate"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip-text" translatable="yes">Set the average bitrate. The instantaneous bitrate can be much higher or lower at any point in time. But the average over a long duration will be the value set here. If you need to limit instantaneous bitrate, look into x264's vbv-bufsize and vbv-maxrate settings.</property> - <property name="label" translatable="yes">Bitrate (kbps): </property> - <property name="group">vquality_type_constant</property> - <property name="draw_indicator">True</property> - <signal handler="setting_widget_changed_cb" name="toggled"/> - </object> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options">GTK_FILL</property> - <property name="x_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkSpinButton" id="VideoAvgBitrate"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip-text" translatable="yes">Set the average bitrate. The instantaneous bitrate can be much higher or lower at any point in time. But the average over a long duration will be the value set here. If you need to limit instantaneous bitrate, look into x264 vbv-bufsize and vbv-maxrate.</property> - <property name="adjustment">adjustment3</property> - <signal handler="setting_widget_changed_cb" name="value_changed"/> - </object> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options">GTK_FILL</property> - <property name="x_options"></property> - </packing> - </child> - <child> - <object class="GtkCheckButton" id="VideoTwoPass"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip-text" translatable="yes">Perform 2 Pass Encoding. The 'Bitrate' option is prerequisite. During the 1st pass, statistics about the video are collected. Then in the second pass, those statistics are used to make bitrate allocation decisions.</property> - <property name="label" translatable="yes">2-Pass Encoding</property> - <property name="draw_indicator">True</property> - <signal handler="setting_widget_changed_cb" name="toggled"/> - </object> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="y_options">GTK_FILL</property> - <property name="x_options">GTK_FILL</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment13"> - <property name="visible">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="left_padding">16</property> + You should generally set this option to the slowest you can bear since slower settings will result in better quality or smaller files.</property> + <property name="adjustment">x264PresetRange</property> + <property name="digits">0</property> + <property name="value_pos">GTK_POS_RIGHT</property> + <signal handler="x264_setting_changed_cb" name="value_changed"/> + <signal handler="format_x264_preset_cb" name="format-value"/> + </object> + <packing> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="left_attach">1</property> + <property name="right_attach">6</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL|GTK_EXPAND</property> + </packing> + </child> <child> - <object class="GtkCheckButton" id="VideoTurboTwoPass"> + <object class="GtkLabel" id="x264TuneLabel"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">x264 Tune:</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="x264Tune"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Tune settings to optimize for common scenarios. + + This can improve effeciency for particular source characteristics or set characteristics of the output file. + + Changes will be applied after the preset but before all other parameters.</property> + <signal handler="x264_setting_changed_cb" name="changed"/> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="x264FastDecode"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip-text" translatable="yes">During the 1st pass of a 2 pass encode, use settings that speed things along.</property> - <property name="label" translatable="yes">Turbo First Pass</property> - <property name="active">True</property> + <property name="tooltip-text" translatable="yes">Reduce decoder CPU usage. + + Set this if your device is struggling to play the output (dropped frames).</property> + <property name="label" translatable="yes">Fast Decode</property> + <property name="active">False</property> <property name="draw_indicator">True</property> - <signal handler="setting_widget_changed_cb" name="toggled"/> + <signal handler="x264_setting_changed_cb" name="toggled"/> </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + <property name="x_padding">20</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="x264ZeroLatency"> + <property name="visible">False</property> + <property name="can_focus">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Minimize latency between input to encoder and output of decoder. + + This is useful for broadcast of live streams. + Since HandBrake is not suitable for live stream broadcast purposes, this setting is of little value here.</property> + <property name="label" translatable="yes">Zero Latency</property> + <property name="active">False</property> + <property name="draw_indicator">True</property> + <signal handler="x264_setting_changed_cb" name="toggled"/> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + <property name="x_padding">20</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="h264ProfileLabel"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">H.264 Profile:</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="h264Profile"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Limit the H.264 profile of the output stream. + + Overrides all other settings.</property> + <signal handler="x264_setting_changed_cb" name="changed"/> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="h264LevelLabel"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">H.264 Level:</property> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="h264Level"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="tooltip-text" translatable="yes">Sets and ensures compliance with the specified H.264 level. + + Overrides all other settings.</property> + <signal handler="x264_setting_changed_cb" name="changed"/> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkHBox" id="hbox43"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="spacing">5</property> + <child> + <object class="GtkLabel" id="x264OptionExtraLabel"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">More Settings:</property> + </object> + <packing> + <property name="position">0</property> + <property name="expand">False</property> + <property name="padding">5</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow8"> + <property name="height_request">60</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">etched-in</property> + <child> + <object class="GtkTextView" id="x264OptionExtra"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip-text" translatable="yes">Additional x264 settings. + + Colon separated list of x264 options.</property> + <property name="wrap_mode">GTK_WRAP_CHAR</property> + <property name="accepts_tab">False</property> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">4</property> + <property name="left_attach">2</property> + <property name="right_attach">6</property> + <property name="y_options"></property> + <property name="x_options">GTK_FILL</property> + </packing> </child> </object> <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">4</property> - <property name="bottom_attach">5</property> - <property name="y_options">GTK_FILL</property> - <property name="x_options">GTK_FILL</property> + <property name="expand">True</property> + <property name="padding">2</property> + <property name="position">1</property> </packing> </child> </object> </child> </object> <packing> + <property name="expand">True</property> <property name="padding">2</property> <property name="position">1</property> </packing> @@ -4819,7 +5137,7 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property> <property name="visible">True</property> <property name="left_padding">12</property> <child> - <object class="GtkNotebook" id="notebook2"> + <object class="GtkNotebook" id="PrefsNotebook"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="show-border">False</property> @@ -5266,19 +5584,22 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property> </packing> </child> <child> - <object class="GtkVBox" id="vbox1"> - <property name="orientation">vertical</property> + <object class="GtkAlignment" id="alignment3"> <property name="visible">True</property> + <property name="top_padding">6</property> + <property name="bottom_padding">6</property> + <property name="left_padding">12</property> <child> - <object class="GtkAlignment" id="alignment3"> + <object class="GtkVBox" id="vbox1"> + <property name="orientation">vertical</property> <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="bottom_padding">6</property> - <property name="left_padding">12</property> <child> - <object class="GtkVBox" id="vbox3"> - <property name="orientation">vertical</property> + <object class="GtkTable" id="AdvancedPrefsTable"> <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="n_rows">9</property> + <property name="n_columns">2</property> + <property name="row_spacing">6</property> <child> <object class="GtkHBox" id="hbox6"> <property name="visible">True</property> @@ -5305,50 +5626,16 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property> </packing> </child> </object> + <packing> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + </packing> </child> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment2"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="bottom_padding">6</property> - <property name="left_padding">12</property> - <child> - <object class="GtkCheckButton" id="use_dvdnav"> - <property name="label" translatable="yes">Use dvdnav (instead of libdvdread)</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="draw_indicator">True</property> - <signal name="toggled" handler="pref_changed_cb"/> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment17"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="bottom_padding">6</property> - <property name="left_padding">12</property> - <child> - <object class="GtkVBox" id="vbox2"> - <property name="orientation">vertical</property> - <property name="visible">True</property> <child> - <object class="GtkCheckButton" id="EncodeLogLocation"> - <property name="label" translatable="yes">Put individual encode logs in same location as movie</property> + <object class="GtkCheckButton" id="use_dvdnav"> + <property name="label" translatable="yes">Use dvdnav (instead of libdvdread)</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -5356,171 +5643,195 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property> <signal name="toggled" handler="pref_changed_cb"/> </object> <packing> - <property name="expand">False</property> - <property name="position">0</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> </packing> </child> <child> - <object class="GtkAlignment" id="alignment51"> + <object class="GtkVBox" id="vbox2"> + <property name="orientation">vertical</property> <property name="visible">True</property> - <property name="left_padding">21</property> <child> - <object class="GtkHBox" id="hbox50"> + <object class="GtkCheckButton" id="EncodeLogLocation"> + <property name="label" translatable="yes">Put individual encode logs in same location as movie</property> <property name="visible">True</property> - <property name="spacing">4</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="pref_changed_cb"/> + </object> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="alignment51"> + <property name="visible">True</property> + <property name="left_padding">21</property> <child> - <object class="GtkComboBox" id="LoggingLevel"> - <property name="width_request">55</property> + <object class="GtkHBox" id="hbox50"> <property name="visible">True</property> - <signal name="changed" handler="pref_changed_cb"/> + <property name="spacing">4</property> + <child> + <object class="GtkComboBox" id="LoggingLevel"> + <property name="width_request">55</property> + <property name="visible">True</property> + <signal name="changed" handler="pref_changed_cb"/> + </object> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Activity Log Verbosity Level</property> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> </object> - <packing> - <property name="expand">False</property> - <property name="position">0</property> - </packing> </child> + </object> + <packing> + <property name="expand">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="alignment63"> + <property name="visible">True</property> + <property name="left_padding">21</property> <child> - <object class="GtkLabel" id="label1"> + <object class="GtkHBox" id="hbox83"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Activity Log Verbosity Level</property> + <property name="spacing">4</property> + <child> + <object class="GtkComboBox" id="LogLongevity"> + <property name="visible">True</property> + <signal name="changed" handler="pref_changed_cb"/> + </object> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="labela2"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Activity Log Longevity</property> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> </object> - <packing> - <property name="position">1</property> - </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="position">2</property> + </packing> </child> </object> <packing> - <property name="expand">False</property> - <property name="position">1</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> </packing> </child> <child> - <object class="GtkAlignment" id="alignment63"> + <object class="GtkCheckButton" id="reduce_hd_preview"> + <property name="label" translatable="yes">Scale down High Definition previews</property> <property name="visible">True</property> - <property name="left_padding">21</property> - <child> - <object class="GtkHBox" id="hbox83"> - <property name="visible">True</property> - <property name="spacing">4</property> - <child> - <object class="GtkComboBox" id="LogLongevity"> - <property name="visible">True</property> - <signal name="changed" handler="pref_changed_cb"/> - </object> - <packing> - <property name="expand">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="labela2"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Activity Log Longevity</property> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - </child> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="pref_changed_cb"/> </object> <packing> - <property name="expand">False</property> - <property name="position">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="AutoScan"> + <property name="label" translatable="yes">Automatically Scan DVD when loaded</property> + <property name="tooltip-text" translatable="yes">Scans the DVD whenever a new disc is loaded</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="pref_changed_cb"/> + </object> + <packing> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="AdvancedAutoPassthru"> + <property name="label" translatable="yes">Enable Advanced Auto-Passthru options</property> + <property name="tooltip-text" translatable="yes">Enabling this adds extra widgets to the audio panel that allow + you to specify which particular codecs shall be passed + and which codec to use when passthru is not possible</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="advanced_audio_changed_cb"/> + </object> + <packing> + <property name="top_attach">5</property> + <property name="bottom_attach">6</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="HideAdvancedVideoSettings"> + <property name="label" translatable="yes">Hide Advanced Video Options Tab</property> + <property name="tooltip-text" translatable="yes">Use advanced video options at your own risk. +We recommend that you use the controls available +on the Video tab instead.</property> + <property name="active">False</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="advanced_video_changed_cb"/> + </object> + <packing> + <property name="top_attach">6</property> + <property name="bottom_attach">7</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment49"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="bottom_padding">6</property> - <property name="left_padding">12</property> - <child> - <object class="GtkCheckButton" id="reduce_hd_preview"> - <property name="label" translatable="yes">Scale down High Definition previews</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="draw_indicator">True</property> - <signal name="toggled" handler="pref_changed_cb"/> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">3</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment48"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="bottom_padding">6</property> - <property name="left_padding">12</property> - <child> - <object class="GtkCheckButton" id="AutoScan"> - <property name="label" translatable="yes">Automatically Scan DVD when loaded</property> - <property name="tooltip-text" translatable="yes">Scans the DVD whenever a new disc is loaded</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="draw_indicator">True</property> - <signal name="toggled" handler="pref_changed_cb"/> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">4</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="alignment65"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="bottom_padding">6</property> - <property name="left_padding">12</property> - <child> - <object class="GtkCheckButton" id="AdvancedAutoPassthru"> - <property name="label" translatable="yes">Enable Advanced Auto-Passthru options</property> - <property name="tooltip-text" translatable="yes">Enabling this adds extra widgets to the audio panel that allow -you to specify which particular codecs shall be passed -and which codec to use when passthru is not possible</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="draw_indicator">True</property> - <signal name="toggled" handler="advanced_audio_changed_cb"/> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">5</property> - </packing> - </child> - <child> - <object class="GtkAlignment" id="hidden_prefs"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="bottom_padding">6</property> - <property name="left_padding">12</property> <child> - <object class="GtkVBox" id="vbox4"> - <property name="orientation">vertical</property> + <object class="GtkTable" id="hidden_prefs"> <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="n_rows">9</property> + <property name="n_columns">2</property> <child> <object class="GtkCheckButton" id="allow_tweaks"> <property name="label" translatable="yes">Allow Tweaks</property> @@ -5530,8 +5841,10 @@ and which codec to use when passthru is not possible</property> <signal name="toggled" handler="tweaks_changed_cb"/> </object> <packing> - <property name="expand">False</property> - <property name="position">0</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> </packing> </child> <child> @@ -5543,17 +5856,19 @@ and which codec to use when passthru is not possible</property> <signal name="toggled" handler="hbfd_feature_changed_cb"/> </object> <packing> - <property name="expand">False</property> - <property name="position">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="left_attach">0</property> + <property name="right_attach">1</property> </packing> </child> </object> + <packing> + <property name="expand">False</property> + <property name="position">1</property> + </packing> </child> </object> - <packing> - <property name="expand">False</property> - <property name="position">6</property> - </packing> </child> </object> <packing> diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index fe02eb966..65fa4ae25 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -2040,6 +2040,120 @@ title_opts_set(GtkBuilder *builder, const gchar *name) titles[ii] = NULL; } +static void +x264_tune_opts_set(GtkBuilder *builder, const gchar *name) +{ + GtkTreeIter iter; + GtkListStore *store; + gint ii, count = 0; + + const char * const *tunes; + tunes = hb_x264_tunes(); + while (tunes && tunes[count]) count++; + + g_debug("x264_tune_opts_set ()\n"); + store = get_combo_box_store(builder, name); + gtk_list_store_clear(store); + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, "None", + 1, TRUE, + 2, "none", + 3, (gdouble)0, + 4, "none", + -1); + + for (ii = 0; ii < count; ii++) + { + if (strcmp(tunes[ii], "fastdecode") && strcmp(tunes[ii], "zerolatency")) + { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, tunes[ii], + 1, TRUE, + 2, tunes[ii], + 3, (gdouble)ii + 1, + 4, tunes[ii], + -1); + } + } +} + +static void +x264_profile_opts_set(GtkBuilder *builder, const gchar *name) +{ + GtkTreeIter iter; + GtkListStore *store; + gint ii, count = 0; + + const char * const *profiles; + profiles = hb_x264_profiles(); + while (profiles && profiles[count]) count++; + + g_debug("x264_profile_opts_set ()\n"); + store = get_combo_box_store(builder, name); + gtk_list_store_clear(store); + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, "Auto", + 1, TRUE, + 2, "auto", + 3, (gdouble)0, + 4, "auto", + -1); + + for (ii = 0; ii < count; ii++) + { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, profiles[ii], + 1, TRUE, + 2, profiles[ii], + 3, (gdouble)ii + 1, + 4, profiles[ii], + -1); + } +} + +static void +x264_level_opts_set(GtkBuilder *builder, const gchar *name) +{ + GtkTreeIter iter; + GtkListStore *store; + gint ii, count = 0; + + const char * const *levels; + levels = hb_h264_levels(); + while (levels && levels[count]) count++; + + g_debug("x264_level_opts_set ()\n"); + store = get_combo_box_store(builder, name); + gtk_list_store_clear(store); + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, "Auto", + 1, TRUE, + 2, "auto", + 3, (gdouble)0, + 4, "auto", + -1); + + for (ii = 0; ii < count; ii++) + { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, levels[ii], + 1, TRUE, + 2, levels[ii], + 3, (gdouble)ii + 1, + 4, levels[ii], + -1); + } +} + int ghb_get_title_count() { @@ -2912,6 +3026,9 @@ ghb_update_ui_combo_box( small_opts_set(ud->builder, "x264_subme", &subme_opts); small_opts_set(ud->builder, "x264_analyse", &analyse_opts); small_opts_set(ud->builder, "x264_trellis", &trellis_opts); + x264_tune_opts_set(ud->builder, "x264Tune"); + x264_profile_opts_set(ud->builder, "h264Profile"); + x264_level_opts_set(ud->builder, "h264Level"); } else { @@ -2941,6 +3058,12 @@ ghb_update_ui_combo_box( subtitle_track_opts_set(ud->builder, "SubtitleTrack", user_data); else if (strcmp(name, "AudioTrack") == 0) audio_track_opts_set(ud->builder, "AudioTrack", user_data); + else if (strcmp(name, "x264Tune") == 0) + x264_tune_opts_set(ud->builder, "x264Tune"); + else if (strcmp(name, "h264Profile") == 0) + x264_profile_opts_set(ud->builder, "h264Profile"); + else if (strcmp(name, "h264Level") == 0) + x264_level_opts_set(ud->builder, "h264Level"); else generic_opts_set(ud->builder, name, find_combo_table(name)); } @@ -2967,6 +3090,9 @@ init_ui_combo_boxes(GtkBuilder *builder) init_combo_box(builder, "VideoEncoder"); init_combo_box(builder, "AudioEncoder"); init_combo_box(builder, "AudioEncoderFallback"); + init_combo_box(builder, "x264Tune"); + init_combo_box(builder, "h264Profile"); + init_combo_box(builder, "h264Level"); for (ii = 0; combo_name_map[ii].name != NULL; ii++) { init_combo_box(builder, combo_name_map[ii].name); @@ -3020,6 +3146,81 @@ ghb_build_advanced_opts_string(GValue *settings) return result; } +void ghb_set_video_encoder_opts(hb_job_t *job, GValue *js) +{ + gint vcodec = ghb_settings_combo_int(js, "VideoEncoder"); + + switch (vcodec) + { + case HB_VCODEC_X264: + { + if (ghb_settings_get_boolean(js, "x264UseAdvancedOptions")) + { + char *opts = ghb_settings_get_string(js, "x264Option"); + hb_job_set_advanced_opts(job, opts); + g_free(opts); + } + else + { + GString *str = g_string_new(""); + char *preset = ghb_settings_get_string(js, "x264Preset"); + char *tune = ghb_settings_get_string(js, "x264Tune"); + char *profile = ghb_settings_get_string(js, "h264Profile"); + char *level = ghb_settings_get_string(js, "h264Level"); + char *opts = ghb_settings_get_string(js, "x264OptionExtra"); + char *tunes; + + g_string_append_printf(str, "%s", tune); + if (ghb_settings_get_boolean(js, "x264FastDecode")) + { + g_string_append_printf(str, "%s%s", str->str[0] ? "," : "", "fastdecode"); + } + if (ghb_settings_get_boolean(js, "x264ZeroLatency")) + { + g_string_append_printf(str, "%s%s", str->str[0] ? "," : "", "zerolatency"); + } + tunes = g_string_free(str, FALSE); + + hb_job_set_x264_preset(job, preset); + + if (tunes != NULL && strcasecmp(tune, "none")) + hb_job_set_x264_tune(job, tunes); + + if (profile != NULL && strcasecmp(profile, "auto")) + hb_job_set_x264_profile(job, profile); + + if (level != NULL && strcasecmp(level, "auto")) + hb_job_set_x264_level(job, level); + + hb_job_set_advanced_opts(job, opts); + + g_free(preset); + g_free(tune); + g_free(profile); + g_free(level); + g_free(opts); + g_free(tunes); + } + } break; + + case HB_VCODEC_FFMPEG_MPEG2: + case HB_VCODEC_FFMPEG_MPEG4: + { + gchar *opts = ghb_settings_get_string(js, "lavcOption"); + if (opts != NULL && opts[0]) + { + hb_job_set_advanced_opts(job, opts); + } + g_free(opts); + } break; + + case HB_VCODEC_THEORA: + default: + { + } break; + } +} + void ghb_part_duration(gint tt, gint sc, gint ec, gint *hh, gint *mm, gint *ss) { @@ -4465,7 +4666,6 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) hb_list_t * list; hb_title_t * title; hb_job_t * job; - static gchar *advanced_opts; gint sub_id = 0; hb_filter_object_t * filter; gchar *filter_str; @@ -4724,6 +4924,13 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) else cfr = 0; + // x264 zero latency requires CFR encode + if (ghb_settings_get_boolean(js, "x264ZeroLatency")) + { + cfr = 1; + ghb_log("zerolatency x264 tune selected, forcing constant framerate"); + } + if( vrate_base == 0 ) { vrate = title->rate; @@ -4935,19 +5142,6 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) } - // TODO: libhb holds onto a reference to the advanced_opts and is not - // finished with it until encoding the job is done. But I can't - // find a way to get at the job before it is removed in order to - // free up the memory I am allocating here. - // The short story is THIS LEAKS. - advanced_opts = ghb_build_advanced_opts_string(js); - - if( advanced_opts && *advanced_opts == '\0' ) - { - g_free(advanced_opts); - advanced_opts = NULL; - } - char * meta; meta = ghb_settings_get_string(js, "MetaName"); @@ -5028,7 +5222,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) */ job->pass = 1; job->indepth_scan = 0; - hb_job_set_advanced_opts(job, advanced_opts); + ghb_set_video_encoder_opts(job, js); /* * If turbo options have been selected then set job->fastfirstpass @@ -5059,13 +5253,12 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex) } else { - hb_job_set_advanced_opts(job, advanced_opts); + ghb_set_video_encoder_opts(job, js); job->indepth_scan = 0; job->pass = 0; job->sequence_id = (unique_id & 0xFFFFFF) | (sub_id++ << 24); hb_add( h, job ); } - g_free(advanced_opts); hb_job_close(&job); } diff --git a/gtk/src/internal_defaults.xml b/gtk/src/internal_defaults.xml index e5d98cebe..466c4234c 100644 --- a/gtk/src/internal_defaults.xml +++ b/gtk/src/internal_defaults.xml @@ -141,6 +141,8 @@ </dict> <key>Preferences</key> <dict> + <key>HideAdvancedVideoSettings</key> + <false /> <key>AdvancedAutoPassthru</key> <false /> <key>AutoScan</key> @@ -244,6 +246,12 @@ <false /> <key>PictureDeinterlaceDecomb</key> <false /> + <key>x264PresetSlider</key> + <integer>0</integer> + <key>x264ZeroLatency</key> + <false /> + <key>x264FastDecode</key> + <false /> </dict> <key>Presets</key> <dict> @@ -397,6 +405,18 @@ <string></string> <key>x264Option</key> <string></string> + <key>x264Preset</key> + <string>custom</string> + <key>x264Tune</key> + <string></string> + <key>h264Profile</key> + <string></string> + <key>h264Level</key> + <string></string> + <key>x264UseAdvancedOptions</key> + <true /> + <key>x264OptionExtra</key> + <string></string> </dict> </dict> </plist> diff --git a/gtk/src/main.c b/gtk/src/main.c index eede9b2ac..0d84725f5 100644 --- a/gtk/src/main.c +++ b/gtk/src/main.c @@ -720,6 +720,7 @@ watch_volumes(signal_user_data_t *ud) } G_MODULE_EXPORT void x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud); +G_MODULE_EXPORT void x264_option_changed_cb(GtkWidget *widget, signal_user_data_t *ud); void preview_window_expose_cb(void); // Some style definitions for the preview window and hud @@ -859,6 +860,10 @@ main (int argc, char *argv[]) buffer = gtk_text_view_get_buffer (textview); g_signal_connect(buffer, "changed", (GCallback)x264_entry_changed_cb, ud); + textview = GTK_TEXT_VIEW(GHB_WIDGET (ud->builder, "x264OptionExtra")); + buffer = gtk_text_view_get_buffer (textview); + g_signal_connect(buffer, "changed", (GCallback)x264_option_changed_cb, ud); + ghb_combo_init(ud); g_debug("ud %p\n", ud); @@ -874,6 +879,13 @@ main (int argc, char *argv[]) // to the callbacks. Builder's standard autoconnect doesn't all this. gtk_builder_connect_signals_full (ud->builder, MyConnect, ud); + GtkWidget *presetSlider = GHB_WIDGET(ud->builder, "x264PresetSlider"); + const char * const *x264_presets; + int count = 0; + x264_presets = hb_x264_presets(); + while (x264_presets && x264_presets[count]) count++; + gtk_range_set_range (GTK_RANGE(presetSlider), 0, count-1); + // Load all internal settings ghb_settings_init(ud); // Load the presets files diff --git a/gtk/src/makedeps.py b/gtk/src/makedeps.py index 404ce7cd9..604527a2f 100644 --- a/gtk/src/makedeps.py +++ b/gtk/src/makedeps.py @@ -47,6 +47,7 @@ dep_map = ( DepEntry("PictureAutoCrop", "PictureLeftCrop", "FALSE", False, False), DepEntry("PictureAutoCrop", "PictureRightCrop", "FALSE", False, False), DepEntry("VideoEncoder", "x264_tab", "x264", False, True), + DepEntry("VideoEncoder", "x264VideoSettings", "x264", False, True), DepEntry("VideoEncoder", "lavc_mpeg4_tab", "ffmpeg|ffmpeg4|ffmpeg2", False, True), DepEntry("VideoEncoder", "Mp4iPodCompatible", "x264", False, False), DepEntry("AudioTrackQualityEnable", "AudioTrackQuality", "FALSE", True, False), @@ -79,6 +80,9 @@ dep_map = ( DepEntry("x264_subme", "x264_psy_rd", "<6", True, False), DepEntry("x264_subme", "x264_psy_trell", "<6", True, False), DepEntry("x264_trellis", "x264_psy_trell", "0", True, False), + DepEntry("x264UseAdvancedOptions", "x264VideoSettingsTable", "TRUE", True, False), + DepEntry("x264UseAdvancedOptions", "x264_tab", "FALSE", True, False), + DepEntry("HideAdvancedVideoSettings", "x264UseAdvancedOptions", "TRUE", True, True), DepEntry("use_source_name", "chapters_in_destination", "TRUE", False, False), DepEntry("use_source_name", "title_no_in_destination", "TRUE", False, False), ) diff --git a/gtk/src/presets.c b/gtk/src/presets.c index 1905e5597..43d83eb9b 100644 --- a/gtk/src/presets.c +++ b/gtk/src/presets.c @@ -863,6 +863,24 @@ init_settings_from_dict( } } +static const char * dict_get_string(GValue *dict, const char *key) +{ + GValue *gval = ghb_dict_lookup(dict, key); + + if (gval == NULL) + return NULL; + return g_value_get_string(gval); +} + +static gboolean dict_get_boolean(GValue *dict, const char *key) +{ + GValue *gval = ghb_dict_lookup(dict, key); + + if (gval == NULL) + return FALSE; + return g_value_get_boolean(gval); +} + void init_ui_from_dict( signal_user_data_t *ud, @@ -879,6 +897,8 @@ init_ui_from_dict( while (g_hash_table_iter_next( &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval)) { + if (!strcmp(key, "x264Option")) + continue; val = NULL; if (dict) val = ghb_dict_lookup(dict, key); @@ -886,6 +906,14 @@ init_ui_from_dict( val = gval; ghb_ui_update(ud, key, val); } + + if (ghb_value_boolean(preset_dict_get_value(dict, "x264UseAdvancedOptions"))) + + { + val = ghb_dict_lookup(dict, "x264Option"); + if (val != NULL) + ghb_ui_update(ud, "x264Option", val); + } } static void @@ -2513,7 +2541,6 @@ import_value_xlat(GValue *dict) if (gval) ghb_dict_insert(dict, g_strdup(key), gval); - GValue *sdeflist; GValue *slist; GValue *sdict; @@ -2648,6 +2675,7 @@ import_xlat_preset(GValue *dict) gint vqtype; g_debug("import_xlat_preset ()"); + uses_max = ghb_value_boolean( preset_dict_get_value(dict, "UsesMaxPictureSettings")); uses_pic = ghb_value_int( @@ -2793,6 +2821,90 @@ import_xlat_preset(GValue *dict) } g_free(str); } + + const char * const *preset = hb_x264_presets(); + if (ghb_value_boolean(preset_dict_get_value(dict, "x264UseAdvancedOptions"))) + { + // Force preset/tune/profile/level/opts to conform to option string + ghb_dict_insert(dict, g_strdup("x264Preset"), + ghb_string_value_new("medium")); + ghb_dict_insert(dict, g_strdup("x264Tune"), + ghb_string_value_new("none")); + ghb_dict_insert(dict, g_strdup("h264Profile"), + ghb_string_value_new("auto")); + ghb_dict_insert(dict, g_strdup("h264Level"), + ghb_string_value_new("auto")); + GValue *opt = ghb_dict_lookup(dict, "x264Option"); + ghb_dict_insert(dict, g_strdup("x264OptionExtra"), + ghb_value_dup(opt)); + } + + GValue *x264Preset = ghb_dict_lookup(dict, "x264Preset"); + if (x264Preset != NULL) + { + gchar *str; + str = ghb_value_string(x264Preset); + int ii; + for (ii = 0; preset[ii]; ii++) + { + if (!strcasecmp(str, preset[ii])) + { + ghb_dict_insert(dict, g_strdup("x264PresetSlider"), + ghb_int_value_new(ii)); + } + } + g_free(str); + } + else + { + int ii; + for (ii = 0; preset[ii]; ii++) + { + if (!strcasecmp("medium", preset[ii])) + { + ghb_dict_insert(dict, g_strdup("x264PresetSlider"), + ghb_int_value_new(ii)); + } + } + } + + const char *x264Tune = dict_get_string(dict, "x264Tune"); + if (x264Tune != NULL) + { + char *tune = NULL; + char *tmp = g_strdup(x264Tune); + char *saveptr; + + char * tok = strtok_r(tmp, ",./-+", &saveptr); + while (tok != NULL) + { + if (!strcasecmp(tok, "fastdecode")) + { + ghb_dict_insert(dict, g_strdup("x264FastDecode"), + ghb_boolean_value_new(TRUE)); + } + else if (!strcasecmp(tok, "zerolatency")) + { + ghb_dict_insert(dict, g_strdup("x264ZeroLatency"), + ghb_boolean_value_new(TRUE)); + } + else if (tune == NULL) + { + tune = g_strdup(tok); + } + else + { + ghb_log("Superfluous tunes! %s", tok); + } + tok = strtok_r(NULL, ",./-+", &saveptr); + } + if (tune != NULL) + { + ghb_dict_insert(dict, g_strdup("x264Tune"), + ghb_string_value_new(tune)); + g_free(tune); + } + } } static void @@ -2890,6 +3002,28 @@ export_xlat_preset(GValue *dict) } } + const char *tune = dict_get_string(dict, "x264Tune"); + if (tune != NULL) + { + GString *str = g_string_new(""); + char *tunes; + + g_string_append_printf(str, "%s", tune); + if (dict_get_boolean(dict, "x264FastDecode")) + { + g_string_append_printf(str, ",%s", "fastdecode"); + } + if (dict_get_boolean(dict, "x264ZeroLatency")) + { + g_string_append_printf(str, ",%s", "zerolatency"); + } + tunes = g_string_free(str, FALSE); + ghb_dict_insert(dict, g_strdup("x264Tune"), + ghb_string_value_new(tunes)); + + g_free(tunes); + } + GValue *internal; GHashTableIter iter; gchar *key; @@ -3292,6 +3426,7 @@ settings_save(signal_user_data_t *ud, const GValue *path) !ghb_settings_get_boolean( ud->settings, "PictureHeightEnable") ) ); + store_presets(); ud->dont_clear_presets = TRUE; // Make the new preset the selected item diff --git a/gtk/src/settings.c b/gtk/src/settings.c index 389120351..dbfead67c 100644 --- a/gtk/src/settings.c +++ b/gtk/src/settings.c @@ -554,7 +554,7 @@ update_widget(GtkWidget *widget, const GValue *value) do { gtk_tree_model_get(store, &iter, 2, &shortOpt, -1); - if (strcmp(shortOpt, str) == 0) + if (strcasecmp(shortOpt, str) == 0) { gtk_combo_box_set_active_iter ( GTK_COMBO_BOX(widget), &iter); diff --git a/gtk/src/x264handler.c b/gtk/src/x264handler.c index 0ddd9c52d..248a9137e 100644 --- a/gtk/src/x264handler.c +++ b/gtk/src/x264handler.c @@ -27,6 +27,192 @@ static gchar* sanitize_x264opts(signal_user_data_t *ud, const gchar *options); // Flag needed to prevent x264 options processing from chasing its tail static gboolean ignore_options_update = FALSE; +void ghb_show_hide_advanced_video( signal_user_data_t *ud ) +{ + GtkWidget *nb = GHB_WIDGET(ud->builder, "SettingsNotebook"); + GtkWidget *at = GHB_WIDGET(ud->builder, "advanced_tab"); + + int pgn = gtk_notebook_page_num(GTK_NOTEBOOK(nb), at); + + GtkWidget *pg; + pg = gtk_notebook_get_nth_page(GTK_NOTEBOOK(nb), pgn); + if (ghb_settings_get_boolean(ud->settings, "HideAdvancedVideoSettings")) + { + gtk_widget_hide(pg); + ghb_ui_update(ud, "x264UseAdvancedOptions", ghb_boolean_value(FALSE)); + } + else + { + gtk_widget_show(pg); + } +} + +G_MODULE_EXPORT void +x264_use_advanced_options_changed_cb(GtkWidget *widget, signal_user_data_t *ud) +{ + ghb_widget_to_setting(ud->settings, widget); + + if (ghb_settings_get_boolean(ud->settings, "HideAdvancedVideoSettings") && + ghb_settings_get_boolean(ud->settings, "x264UseAdvancedOptions")) + { + ghb_ui_update(ud, "x264UseAdvancedOptions", ghb_boolean_value(FALSE)); + return; + } + + if (ghb_settings_get_boolean(ud->settings, "x264UseAdvancedOptions")) + { + ghb_ui_update(ud, "x264PresetSlider", ghb_int_value(5)); + ghb_ui_update(ud, "x264Tune", ghb_string_value("none")); + ghb_ui_update(ud, "h264Profile", ghb_string_value("auto")); + ghb_ui_update(ud, "h264Level", ghb_string_value("auto")); + + char *options = ghb_settings_get_string(ud->settings, "x264Option"); + ghb_ui_update(ud, "x264OptionExtra", ghb_string_value(options)); + g_free(options); + } + + ghb_check_dependency(ud, widget, NULL); + ghb_clear_presets_selection(ud); +} + +G_MODULE_EXPORT void +x264_setting_changed_cb(GtkWidget *widget, signal_user_data_t *ud) +{ + static char *tt = NULL; + + + if (tt == NULL) + { + GtkWidget *eo = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264OptionExtra")); + tt = gtk_widget_get_tooltip_text(eo); + } + + ghb_widget_to_setting(ud->settings, widget); + + int x264Preset = ghb_settings_get_int(ud->settings, "x264PresetSlider"); + const char * preset = hb_x264_presets()[x264Preset]; + ghb_settings_set_string(ud->settings, "x264Preset", preset); + + if (!ghb_settings_get_boolean(ud->settings, "x264UseAdvancedOptions")) + { + GString *str = g_string_new(""); + char *preset; + char *tune; + char *profile; + char *level; + char *opts; + char *tunes; + + preset = ghb_settings_get_string(ud->settings, "x264Preset"); + tune = ghb_settings_get_string(ud->settings, "x264Tune"); + profile = ghb_settings_get_string(ud->settings, "h264Profile"); + level = ghb_settings_get_string(ud->settings, "h264Level"); + opts = ghb_settings_get_string(ud->settings, "x264OptionExtra"); + + if (tune[0] && strcmp(tune, "none")) + { + g_string_append_printf(str, "%s", tune); + } + if (ghb_settings_get_boolean(ud->settings, "x264FastDecode")) + { + g_string_append_printf(str, "%s%s", str->str[0] ? "," : "", "fastdecode"); + } + if (ghb_settings_get_boolean(ud->settings, "x264ZeroLatency")) + { + g_string_append_printf(str, "%s%s", str->str[0] ? "," : "", "zerolatency"); + } + tunes = g_string_free(str, FALSE); + + char * new_opts; + + int w = ghb_settings_get_int(ud->settings, "scale_width"); + int h = ghb_settings_get_int(ud->settings, "scale_height"); + + if (w == 0 || h == 0) + { + if (!ghb_settings_get_boolean(ud->settings, "autoscale")) + { + w = ghb_settings_get_int(ud->settings, "PictureWidth"); + h = ghb_settings_get_int(ud->settings, "PictureHeight"); + + if (h == 0 && w != 0) + { + h = w * 9 / 16; + } + if (w == 0 && h != 0) + { + w = h * 16 / 9; + } + } + if (w == 0 || h == 0) + { + w = 1280; + h = 720; + } + } + + if (!strcasecmp(profile, "auto")) + { + profile[0] = 0; + } + if (!strcasecmp(level, "auto")) + { + level[0] = 0; + } + new_opts = hb_x264_param_unparse( + preset, tunes, opts, profile, level, w, h); + if (new_opts) + ghb_ui_update(ud, "x264Option", ghb_string_value(new_opts)); + else + ghb_ui_update(ud, "x264Option", ghb_string_value("")); + + GtkWidget *eo = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264OptionExtra")); + + char * new_tt; + if (new_opts) + new_tt = g_strdup_printf("%s\n\nExpanded Options:\n\"%s\"", tt, new_opts); + else + new_tt = g_strdup_printf("%s\n\nExpanded Options:\n\"\"", tt); + gtk_widget_set_tooltip_text(eo, new_tt); + + g_free(new_tt); + g_free(new_opts); + + g_free(preset); + g_free(tune); + g_free(profile); + g_free(level); + g_free(opts); + g_free(tunes); + } + else + { + char *opts = ghb_settings_get_string(ud->settings, "x264Option"); + + GtkWidget *eo = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264OptionExtra")); + char * new_tt; + if (opts) + new_tt = g_strdup_printf("%s\n\nExpanded Options:\n\"%s\"", tt, opts); + else + new_tt = g_strdup_printf("%s\n\nExpanded Options:\n\"\"", tt); + gtk_widget_set_tooltip_text(eo, new_tt); + + g_free(opts); + } + + ghb_check_dependency(ud, widget, NULL); + ghb_clear_presets_selection(ud); +} + +G_MODULE_EXPORT void +x264_option_changed_cb(GtkWidget *widget, signal_user_data_t *ud) +{ + GtkWidget *textview; + + textview = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264OptionExtra")); + x264_setting_changed_cb(textview, ud); +} + G_MODULE_EXPORT void x264_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { @@ -105,6 +291,15 @@ G_MODULE_EXPORT void x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud) { g_debug("x264_entry_changed_cb ()"); + + static char *tt = NULL; + + if (tt == NULL) + { + GtkWidget *eo = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264OptionExtra")); + tt = gtk_widget_get_tooltip_text(eo); + } + if (!ignore_options_update) { GtkWidget *textview; @@ -113,6 +308,7 @@ x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud) textview = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264Option")); ghb_widget_to_setting(ud->settings, textview); options = ghb_settings_get_string(ud->settings, "x264Option"); + ignore_options_update = TRUE; ghb_x264_parse_options(ud, options); if (!gtk_widget_has_focus(textview)) @@ -122,8 +318,29 @@ x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud) sopts = sanitize_x264opts(ud, options); ghb_ui_update(ud, "x264Option", ghb_string_value(sopts)); ghb_x264_parse_options(ud, sopts); - g_free(sopts); + + GtkWidget *eo = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264OptionExtra")); + char * new_tt; + if (sopts) + new_tt = g_strdup_printf("%s\n\nExpanded Options:\n\"%s\"", tt, sopts); + else + new_tt = g_strdup_printf("%s\n\nExpanded Options:\n\"\"", tt); + gtk_widget_set_tooltip_text(eo, new_tt); + + g_free(options); + options = sopts; } +#if 0 + if (ghb_settings_get_boolean(ud->settings, "x264UseAdvancedOptions")) + { + ghb_ui_update(ud, "x264PresetSlider", ghb_int_value(5)); + ghb_ui_update(ud, "x264Tune", ghb_string_value("none")); + ghb_ui_update(ud, "h264Profile", ghb_string_value("auto")); + ghb_ui_update(ud, "h264Level", ghb_string_value("auto")); + + ghb_ui_update(ud, "x264OptionExtra", ghb_string_value(options)); + } +#endif g_free(options); ignore_options_update = FALSE; } @@ -1090,3 +1307,16 @@ lavc_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, return FALSE; } +G_MODULE_EXPORT gchar* +format_x264_preset_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud) +{ + const char * const *x264_presets; + const char *preset = "medium"; + + x264_presets = hb_x264_presets(); + + preset = x264_presets[(int)val]; + + return g_strdup_printf(" %-12s", preset); +} + diff --git a/gtk/src/x264handler.h b/gtk/src/x264handler.h index 9c671002b..592a4fd3b 100644 --- a/gtk/src/x264handler.h +++ b/gtk/src/x264handler.h @@ -29,5 +29,6 @@ void ghb_x264_parse_options(signal_user_data_t *ud, const gchar *options); gint ghb_lookup_badapt(const gchar *options); +void ghb_show_hide_advanced_video( signal_user_data_t *ud ); #endif // _X264HANDLER_H_ |