OSDN Git Service

LinGui: add CFR option for "Same as source" framerate.
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Fri, 28 Jan 2011 23:18:21 +0000 (23:18 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Fri, 28 Jan 2011 23:18:21 +0000 (23:18 +0000)
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://localhost/HandBrake/trunk@3770 b64f7644-9d1e-0410-96f1-a4d463321fa5

gtk/src/callbacks.c
gtk/src/ghb.ui
gtk/src/hb-backend.c
gtk/src/internal_defaults.xml
gtk/src/makedeps.py
gtk/src/presets.c
gtk/src/settings.c

index f225ff9..3bc6c0d 100644 (file)
@@ -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();
index 71b66db..7297f11 100644 (file)
                                         <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>
                               </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>
                               </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>
                               </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>
                         <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>
index c5e1cad..8029720 100644 (file)
@@ -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;
index 568da2f..67d786f 100644 (file)
                <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>
        </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>
                <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>
index 121c565..2e07eda 100644 (file)
@@ -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),
index db3cd6d..17e0034 100644 (file)
@@ -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);
 }
 
index 34c6497..afe4180 100644 (file)
@@ -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)
        {