]> granicus.if.org Git - handbrake/commitdiff
LinGui: add CFR option for "Same as source" framerate.
authorjstebbins <jstebbins.hb@gmail.com>
Fri, 28 Jan 2011 23:18:21 +0000 (23:18 +0000)
committerjstebbins <jstebbins.hb@gmail.com>
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://svn.handbrake.fr/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 f225ff93aa83e62c48cea7d9ea8bfa8556f87c9f..3bc6c0d414c0fe58175a2f66347d3eaca2e850c5 100644 (file)
@@ -1583,6 +1583,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)
 {
@@ -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 71b66db24cc26f1f326f2f58609f7abbf64e4e41..7297f1177a2d2b607e262bdca35279108727484c 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 c5e1cadf19fe4d86e7ccf21033b311f57958c9a0..80297203cc41d110dbb51c54efe294862a6f08e7 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 568da2fa955e5e8bd71117a9591172c3e2b85575..67d786f63dfcd0c39818d455f18830463c364292 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 121c5654a4b274c56843169bc1082b9929cc651f..2e07eda3ef8f5413197e3171dd4dc0d000ed13ee 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 db3cd6d0cfd3cd0fbc669efb55e3257cd700873d..17e00346b7362ea472f7e5992318b8d308d5e784 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 34c649758dbc6d7923ab18dbdf0ac94072636d0b..afe41803c10c73d6dc8b0a51c866b3c9cb7aa7e8 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)
        {