summaryrefslogtreecommitdiffstats
path: root/gtk/src
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2011-01-28 23:18:21 +0000
committerjstebbins <[email protected]>2011-01-28 23:18:21 +0000
commitf839f412fb7c05e20201d3b09560e5ba085a4fe1 (patch)
tree92be215f512b5801337b3363bbb3ed597a72dcbc /gtk/src
parent5eac1c0562ead268ffa4ace6bf86981c7f884faf (diff)
LinGui: add CFR option for "Same as source" framerate.
Since there seem to be a lot of players that do not properly support VFR, add a CFR option that can be used with "Same as source". The framerate to use comes from the title and the cfr flag is set in the job. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3770 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'gtk/src')
-rw-r--r--gtk/src/callbacks.c26
-rw-r--r--gtk/src/ghb.ui294
-rw-r--r--gtk/src/hb-backend.c12
-rw-r--r--gtk/src/internal_defaults.xml22
-rw-r--r--gtk/src/makedeps.py3
-rw-r--r--gtk/src/presets.c111
-rw-r--r--gtk/src/settings.c44
7 files changed, 353 insertions, 159 deletions
diff --git a/gtk/src/callbacks.c b/gtk/src/callbacks.c
index f225ff93a..3bc6c0d41 100644
--- a/gtk/src/callbacks.c
+++ b/gtk/src/callbacks.c
@@ -1584,6 +1584,28 @@ ptop_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
}
G_MODULE_EXPORT void
+framerate_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ ghb_widget_to_setting(ud->settings, widget);
+
+ if (ghb_settings_combo_int(ud->settings, "VideoFramerate") != 0)
+ {
+ if (!ghb_settings_get_boolean(ud->settings, "VideoFrameratePFR"))
+ {
+ ghb_ui_update(ud, "VideoFramerateCFR", ghb_boolean_value(TRUE));
+ }
+ }
+ if (ghb_settings_combo_int(ud->settings, "VideoFramerate") == 0 &&
+ ghb_settings_get_boolean(ud->settings, "VideoFrameratePFR"))
+ {
+ ghb_ui_update(ud, "VideoFramerateVFR", ghb_boolean_value(TRUE));
+ }
+ ghb_check_dependency(ud, widget, NULL);
+ ghb_clear_presets_selection(ud);
+ ghb_live_reset(ud);
+}
+
+G_MODULE_EXPORT void
setting_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
ghb_widget_to_setting(ud->settings, widget);
@@ -2159,7 +2181,7 @@ ghb_cancel_encode(signal_user_data_t *ud, const gchar *extra_msg)
NULL);
response = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy (dialog);
- switch (response)
+ switch ((int)response)
{
case 1:
ghb_stop_queue();
@@ -2197,7 +2219,7 @@ ghb_cancel_encode2(signal_user_data_t *ud, const gchar *extra_msg)
NULL);
response = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy (dialog);
- switch (response)
+ switch ((int)response)
{
case 1:
ghb_stop_queue();
diff --git a/gtk/src/ghb.ui b/gtk/src/ghb.ui
index 71b66db24..7297f1177 100644
--- a/gtk/src/ghb.ui
+++ b/gtk/src/ghb.ui
@@ -1751,7 +1751,7 @@
<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 recomended. If your source video has a variable framerate, 'Same as source' will preserve it.</property>
- <signal handler="setting_widget_changed_cb" name="changed"/>
+ <signal handler="framerate_changed_cb" name="changed"/>
</object>
</child>
</object>
@@ -1767,12 +1767,12 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="VideoFrameratePFR">
+ <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 variable framerate output with a peak rate determined by the framerate setting</property>
- <property name="label" translatable="yes">Peak Framerate (VFR)</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>
@@ -1782,13 +1782,14 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="VideoTwoPass">
+ <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">Perform 2 Pass Encoding. 'Bitrate' or 'Target Size' options are prerequisites. 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="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>
@@ -1797,22 +1798,15 @@
</packing>
</child>
<child>
- <object class="GtkAlignment" id="alignment13">
+ <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="left_padding">16</property>
- <child>
- <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">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>
+ <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>
@@ -1833,150 +1827,180 @@
<property name="top_padding">48</property>
<property name="right_padding">24</property>
<child>
- <object class="GtkVBox" id="vbox47">
- <property name="orientation">vertical</property>
+ <object class="GtkTable" id="table8">
+ <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="GtkHBox" id="hbox62">
+ <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>
- <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="draw_indicator">True</property>
- <signal handler="setting_widget_changed_cb" name="toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment15">
- <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.11999999731779099</property>
- <property name="xscale">0.10000000149011612</property>
- <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>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
+ <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="position">0</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">GTK_FILL</property>
+ <property name="x_options">GTK_FILL|GTK_EXPAND</property>
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox56">
+ <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>
- <child>
- <object class="GtkRadioButton" id="vquality_type_target">
- <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 final size of the output file. This uses the known duration of the video to calculate the bitrate that will be required to achieve the desired size.</property>
- <property name="label" translatable="yes">Target Size (MB):</property>
- <property name="draw_indicator">True</property>
- <property name="group">vquality_type_bitrate</property>
- <signal handler="target_size_changed_cb" name="toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment16">
- <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.11999999731779099</property>
- <property name="xscale">0.10000000149011612</property>
- <child>
- <object class="GtkSpinButton" id="VideoTargetSize">
- <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 final size of the output file. This uses the known duration of the video to calculate the bitrate that will be required to achieve the desired size.</property>
- <property name="adjustment">adjustment4</property>
- <signal handler="target_size_changed_cb" name="value_changed"/>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
+ <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="expand">False</property>
- <property name="position">1</property>
+ <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="GtkHBox" id="hbox57">
+ <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="GtkRadioButton" id="vquality_type_target">
+ <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 final size of the output file. This uses the known duration of the video to calculate the bitrate that will be required to achieve the desired size.</property>
+ <property name="label" translatable="yes">Target Size (MB):</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">vquality_type_constant</property>
+ <signal handler="target_size_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="GtkSpinButton" id="VideoTargetSize">
+ <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 final size of the output file. This uses the known duration of the video to calculate the bitrate that will be required to achieve the desired size.</property>
+ <property name="adjustment">adjustment4</property>
+ <signal handler="target_size_changed_cb" name="value_changed"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</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. 'Bitrate' or 'Target Size' options are prerequisites. 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">4</property>
+ <property name="bottom_attach">5</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>
<child>
- <object class="GtkRadioButton" id="vquality_type_constant">
+ <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">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="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>
- <property name="group">vquality_type_target</property>
<signal handler="setting_widget_changed_cb" name="toggled"/>
</object>
- <packing>
- <property name="expand">False</property>
- </packing>
</child>
</object>
<packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <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="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_BOTTOM</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="position">3</property>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="y_options">GTK_FILL</property>
+ <property name="x_options">GTK_FILL</property>
</packing>
</child>
</object>
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index c5e1cadf1..80297203c 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -4632,18 +4632,18 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
{
job->vrate = title->rate;
job->vrate_base = title->rate_base;
- job->cfr = 0;
}
else
{
job->vrate = 27000000;
job->vrate_base = vrate;
- gboolean pfr = ghb_settings_get_boolean(js, "VideoFrameratePFR");
- if (pfr)
- job->cfr = 2;
- else
- job->cfr = 1;
}
+ if (ghb_settings_get_boolean(js, "VideoFrameratePFR"))
+ job->cfr = 2;
+ else if (ghb_settings_get_boolean(js, "VideoFramerateCFR"))
+ job->cfr = 1;
+ else
+ job->cfr = 0;
const GValue *audio_list;
gint count, ii;
diff --git a/gtk/src/internal_defaults.xml b/gtk/src/internal_defaults.xml
index 568da2fa9..67d786f63 100644
--- a/gtk/src/internal_defaults.xml
+++ b/gtk/src/internal_defaults.xml
@@ -114,6 +114,12 @@
<string></string>
<key>SrtOffset</key>
<integer>0</integer>
+ <key>VideoFramerateCFR</key>
+ <false />
+ <key>VideoFrameratePFR</key>
+ <false />
+ <key>VideoFramerateVFR</key>
+ <false />
</dict>
<key>Preferences</key>
<dict>
@@ -200,20 +206,20 @@
</dict>
<key>XlatPresets</key>
<dict>
- <key>anamorphic</key>
- <true />
<key>autoscale</key>
<false />
- <key>par_width</key>
- <integer>0</integer>
- <key>par_height</key>
- <integer>0</integer>
<key>vquality_type_bitrate</key>
<false />
<key>vquality_type_constant</key>
<false />
<key>vquality_type_target</key>
<false />
+ <key>VideoFramerateCFR</key>
+ <false />
+ <key>VideoFrameratePFR</key>
+ <false />
+ <key>VideoFramerateVFR</key>
+ <false />
</dict>
<key>Presets</key>
<dict>
@@ -273,8 +279,8 @@
<integer>0</integer>
<key>VideoFramerate</key>
<string>source</string>
- <key>VideoFrameratePFR</key>
- <false />
+ <key>VideoFramerateMode</key>
+ <string>vfr</string>
<key>VideoGrayScale</key>
<false />
<key>Mp4HttpOptimize</key>
diff --git a/gtk/src/makedeps.py b/gtk/src/makedeps.py
index 121c5654a..2e07eda3e 100644
--- a/gtk/src/makedeps.py
+++ b/gtk/src/makedeps.py
@@ -25,7 +25,8 @@ dep_map = (
DepEntry("vquality_type_constant", "VideoQualitySlider", "TRUE", False, False),
DepEntry("vquality_type_constant", "VideoTwoPass", "TRUE", True, False),
DepEntry("vquality_type_constant", "VideoTurboTwoPass", "TRUE", True, False),
- DepEntry("VideoFramerate", "VideoFrameratePFR", "source", True, False),
+ DepEntry("VideoFramerate", "VideoFrameratePFR", "source", True, True),
+ DepEntry("VideoFramerate", "VideoFramerateVFR", "source", False, True),
DepEntry("VideoTwoPass", "VideoTurboTwoPass", "TRUE", False, False),
DepEntry("FileFormat", "Mp4LargeFile", "mp4", False, True),
DepEntry("FileFormat", "Mp4HttpOptimize", "mp4", False, True),
diff --git a/gtk/src/presets.c b/gtk/src/presets.c
index db3cd6d0c..17e00346b 100644
--- a/gtk/src/presets.c
+++ b/gtk/src/presets.c
@@ -2682,8 +2682,81 @@ import_xlat_preset(GValue *dict)
ghb_boolean_value_new(TRUE));
} break;
}
+
import_value_xlat(dict);
+ GValue *mode = ghb_dict_lookup(dict, "VideoFramerateMode");
+ if (mode == NULL)
+ {
+ GValue *fr = ghb_dict_lookup(dict, "VideoFramerate");
+ if (fr)
+ {
+ gchar *str;
+ gboolean pfr = FALSE;
+ GValue *pfr_val = ghb_dict_lookup(dict, "VideoFrameratePFR");
+ if (pfr_val)
+ {
+ pfr = ghb_value_boolean(pfr_val);
+ }
+ str = ghb_value_string(fr);
+ if (strcmp(str, "source") == 0)
+ {
+ ghb_dict_insert(dict, g_strdup("VideoFramerateCFR"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("VideoFramerateVFR"),
+ ghb_boolean_value_new(TRUE));
+ }
+ else if (!pfr)
+ {
+ ghb_dict_insert(dict, g_strdup("VideoFramerateCFR"),
+ ghb_boolean_value_new(TRUE));
+ ghb_dict_insert(dict, g_strdup("VideoFramerateVFR"),
+ ghb_boolean_value_new(FALSE));
+ }
+ else
+ {
+ ghb_dict_insert(dict, g_strdup("VideoFramerateCFR"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("VideoFramerateVFR"),
+ ghb_boolean_value_new(FALSE));
+ }
+ g_free(str);
+ }
+ }
+ else
+ {
+ gchar *str;
+ str = ghb_value_string(mode);
+ if (strcmp(str, "cfr") == 0)
+ {
+ ghb_dict_insert(dict, g_strdup("VideoFramerateCFR"),
+ ghb_boolean_value_new(TRUE));
+ ghb_dict_insert(dict, g_strdup("VideoFrameratePFR"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("VideoFramerateVFR"),
+ ghb_boolean_value_new(FALSE));
+ }
+ else if (strcmp(str, "pfr") == 0)
+ {
+ ghb_dict_insert(dict, g_strdup("VideoFramerateCFR"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("VideoFrameratePFR"),
+ ghb_boolean_value_new(TRUE));
+ ghb_dict_insert(dict, g_strdup("VideoFramerateVFR"),
+ ghb_boolean_value_new(FALSE));
+ }
+ else
+ {
+ ghb_dict_insert(dict, g_strdup("VideoFramerateCFR"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("VideoFrameratePFR"),
+ ghb_boolean_value_new(FALSE));
+ ghb_dict_insert(dict, g_strdup("VideoFramerateVFR"),
+ ghb_boolean_value_new(TRUE));
+ }
+ g_free(str);
+ }
+
gdouble vquality;
const GValue *gval;
@@ -2787,6 +2860,22 @@ export_xlat_preset(GValue *dict)
ghb_int_value_new(2));
}
+ if (ghb_value_boolean(preset_dict_get_value(dict, "VideoFramerateCFR")))
+ {
+ ghb_dict_insert(dict, g_strdup("VideoFramerateMode"),
+ ghb_string_value_new("cfr"));
+ }
+ else if (ghb_value_boolean(preset_dict_get_value(dict, "VideoFrameratePFR")))
+ {
+ ghb_dict_insert(dict, g_strdup("VideoFramerateMode"),
+ ghb_string_value_new("pfr"));
+ }
+ else
+ {
+ ghb_dict_insert(dict, g_strdup("VideoFramerateMode"),
+ ghb_string_value_new("vfr"));
+ }
+
GValue *alist, *adict;
gint count, ii;
@@ -2806,11 +2895,25 @@ export_xlat_preset(GValue *dict)
}
}
+ GValue *internal;
+ GHashTableIter iter;
+ gchar *key;
+ GValue *value;
+ internal = plist_get_dict(internalPlist, "XlatPresets");
+ ghb_dict_iter_init(&iter, internal);
+ // middle (void*) cast prevents gcc warning "defreferencing type-punned
+ // pointer will break strict-aliasing rules"
+ while (g_hash_table_iter_next(
+ &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
+ {
+ ghb_dict_remove(dict, key);
+ }
+
+ // remove obsolete keys
ghb_dict_remove(dict, "UsesMaxPictureSettings");
- ghb_dict_remove(dict, "autoscale");
- ghb_dict_remove(dict, "vquality_type_target");
- ghb_dict_remove(dict, "vquality_type_bitrate");
- ghb_dict_remove(dict, "vquality_type_constant");
+ ghb_dict_remove(dict, "VFR");
+ ghb_dict_remove(dict, "VideoFrameratePFR");
+
export_value_xlat(dict);
}
diff --git a/gtk/src/settings.c b/gtk/src/settings.c
index 34c649758..afe41803c 100644
--- a/gtk/src/settings.c
+++ b/gtk/src/settings.c
@@ -222,8 +222,16 @@ ghb_widget_value(GtkWidget *widget)
{
g_debug("\tradio_button");
gboolean bval;
- bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- value = ghb_boolean_value_new(bval);
+ bval = gtk_toggle_button_get_inconsistent(GTK_TOGGLE_BUTTON(widget));
+ if (bval)
+ {
+ value = ghb_boolean_value_new(FALSE);
+ }
+ else
+ {
+ bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ value = ghb_boolean_value_new(bval);
+ }
}
else if (type == GTK_TYPE_CHECK_BUTTON)
{
@@ -427,6 +435,26 @@ ghb_widget_boolean(GtkWidget *widget)
return bval;
}
+static void check_radio_consistency(GValue *settings, GtkWidget *widget)
+{
+ const gchar *key = NULL;
+ GValue *value;
+
+ if (widget == NULL) return;
+ if (G_OBJECT_TYPE(widget) == GTK_TYPE_RADIO_BUTTON)
+ {
+ // Find corresponding setting
+ key = ghb_get_setting_key(widget);
+ if (key == NULL) return;
+ value = ghb_widget_value(widget);
+ if (value == NULL) return;
+ if (ghb_value_boolean(value) == ghb_settings_get_boolean(settings, key))
+ {
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(widget), FALSE);
+ }
+ }
+}
+
void
ghb_widget_to_setting(GValue *settings, GtkWidget *widget)
{
@@ -441,6 +469,7 @@ ghb_widget_to_setting(GValue *settings, GtkWidget *widget)
value = ghb_widget_value(widget);
if (value != NULL)
{
+ check_radio_consistency(settings, widget);
ghb_settings_take_value(settings, key, value);
}
else
@@ -474,7 +503,16 @@ update_widget(GtkWidget *widget, const GValue *value)
else if (type == GTK_TYPE_RADIO_BUTTON)
{
g_debug("radio button");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
+ int cur_val = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ if (cur_val && !ival)
+ {
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(widget), TRUE);
+ }
+ else
+ {
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(widget), FALSE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
+ }
}
else if (type == GTK_TYPE_CHECK_BUTTON)
{